我正在使用 H2 数据库,我可以看到父表(ConnectionInfo)中的数据已删除,但数据存在于子表(DeployedComponent)中。 当执行删除查询以从子表中删除数据时,我收到引用实体错误:
错误信息:
Hibernate: delete from deploy_center.deployed_comp_property where DEPLOYED_COMP_PROP_ID=?
Hibernate: delete from deploy_center.deployed_component where DEPLOYED_COMPONENT_ID=?
2024-02-13 20:24:45 WARN SqlExceptionHelper:137 - SQL Error: 23503, SQLState: 23503
2024-02-13 20:24:45 ERROR SqlExceptionHelper:142 - Referential integrity constraint violation: "FK__CONNECTION_INFO__DEPLOYED_COMPONENT__DEPLOYED_COMP: DEPLOY_CENTER.CONNECTION_INFO FOREIGN KEY(DEPLOYED_COMP) REFERENCES DEPLOY_CENTER.DEPLOYED_COMPONENT(DEPLOYED_COMPONENT_ID) (CAST(257 AS BIGINT))"; SQL statement:
delete from deploy_center.deployed_component where DEPLOYED_COMPONENT_ID=? [23503-212]
2024-02-13 20:24:45 INFO AbstractBatchImpl:208 - HHH000010: On release of batch it still contained JDBC statements
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["FK__CONNECTION_INFO__DEPLOYED_COMPONENT__DEPLOYED_COMP: DEPLOY_CENTER.CONNECTION_INFO FOREIGN KEY(DEPLOYED_COMP) REFERENCES DEPLOY_CENTER.DEPLOYED_COMPONENT(DEPLOYED_COMPONENT_ID) (CAST(257 AS BIGINT))"; SQL statement:
delete from deploy_center.deployed_component where DEPLOYED_COMPONENT_ID=? [23503-212]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:276)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingM
由于 for 循环,还有另外 2 个 jpa 方法,它们在执行 findBy 之前从“ConnectionInfo”和“DeployedCOmponents”表中删除数据。
因此,由于 for 循环,它会再次执行尝试执行 findBy Query 的其他组件,一旦执行该特定行,我就会收到以下错误。
我的分析如下:基本上我有2个表:a)ConnectionInfo b)Deployed_Component c)Component,它试图从Deployed_Component中获取数据,正如方法名称所示“findByObsoletedFalseAndComponentNameAndEnvironmentEnvId”,但这里它自己抛出了错误
updateBreadCrumbTranscation2(Environment environment, DeployedComponent currentDeployedComponent,
Map<ComponentId, Component> availableComponentsMap){
// code snnipet .. invoking other methods
evaluateConditionalDependencies();
}
evaluateConditionalDependencies( breadCrumbSoftwareDTO, environment, obsoleteComponentCandidates ){
//code snipppets
BreadCrumbComponent breadCrumbComponent = ( (BreadCrumbComponent) breadCrumbManagerMap.get( DCConstants.COMPONENTS ) );
for ( DeployedComponent deployedComponent : environment.getActiveDeployedComponents() )
{
breadCrumbComponent.evaluateConditionalDependencies( environment, deployedComponent,
breadCrumbComponent.getAvailableComponentsMap( environment ) );
}
//code snipppets
}
public void evaluateConditionalDependencies( Environment environment, DeployedComponent currentDeployedComponent,
Map<ComponentId, Component> availableComponentsMap ){
if{
dependentComponents = deployedComponentRepository
.findByObsoletedFalseAndComponentNameAndEnvironmentEnvId( dependencyCompName, environment.getEnvId() );
}
else{
dependentComponents = deployedComponentRepository
.findByObsoletedFalseAndComponentNameAndEnvironmentEnvId( dependencyCompName, environment.getEnvId() );
}
...
//code snippets
activeDeployedComponent.getConnectionInfosForDeployedComp().removeAll( connectionInfoToBeRemoved );
environment.getDeployedComponents().removeAll( componentDependencies );
}
@Table(name = "connection_info", catalog = "deploy_center", uniqueConstraints = @UniqueConstraint(columnNames = {"DEPLOYED_COMP",
"REFERENCE"}))
public class ConnectionInfo extends AbstractBean implements Comparable<ConnectionInfo>
{
// code snippets
@Transient
public String getUniqueKey()
{
return getUniqueKey( deployedComponentByDeployedComp, deployedComponentByReference );
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REFERENCE", nullable = false, foreignKey = @ForeignKey(name = "fk__connection_info__deployed_component__reference"))
public DeployedComponent getDeployedComponentByReference()
{
return this.deployedComponentByReference;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REFERENCE", nullable = false, foreignKey = @ForeignKey(name = "fk__connection_info__deployed_component__reference"))
public DeployedComponent getDeployedComponentByReference()
{
return this.deployedComponentByReference;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DEPLOYED_COMP", nullable = false, foreignKey = @ForeignKey(name = "fk__connection_info__deployed_component__deployed_comp"))
public DeployedComponent getDeployedComponentByDeployedComp()
{
return this.deployedComponentByDeployedComp;
}
//code snippets
}
@Entity
@Table(name = "deployed_component", catalog = "deploy_center")
public class DeployedComponent extends AbstractBean{
/** The connection infos. */
private Set<ConnectionInfo> connectionInfosForReference = new HashSet<ConnectionInfo>( 0 );
/** The connection infos for deployed comp. */
private Set<ConnectionInfo> connectionInfosForDeployedComp = new HashSet<ConnectionInfo>( 0 );
/** The connection infos for deployed relationship comp. */
private Set<ConnectionInfo> connectionInfosForDeployedRelationshipComp = new HashSet<ConnectionInfo>( 0 );
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "DEPLOYED_COMPONENT_ID", unique = true, nullable = false)
public Long getDeployedComponentId()
{
return this.deployedComponentId;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DEPLOYABLE_COMP_ID", nullable = false, foreignKey = @ForeignKey(name = "fk__deployed_component__component__deployable_comp_id"))
public Component getComponent()
{
return this.component;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ENV_ID", nullable = false, foreignKey = @ForeignKey(name = "fk__deployed_component__environment__env_id"))
public Environment getEnvironment()
{
return this.environment;
}
@ElementCollection
@CollectionTable(name = "inherited_consumer_envrionments", catalog = "deploy_center", joinColumns = @JoinColumn(name = "deployedComponentId"))
@Column(name = "consumer_envrionments")
public Set<Long> getConsumerEnvironments()
{
if ( consumerEnvironments == null )
{
consumerEnvironments = new HashSet<>();
}
return consumerEnvironments;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MACHINE_ID", foreignKey = @ForeignKey(name = "fk__deployed_component__machine__machine_id"))
@org.hibernate.annotations.Cascade({CascadeType.PERSIST, CascadeType.MERGE, CascadeType.SAVE_UPDATE})
public Machine getMachine()
{
return this.machine;
}
*/
@OneToMany(fetch = FetchType.LAZY, mappedBy = "relationshipDeployedComp", orphanRemoval = true)
@org.hibernate.annotations.Cascade({CascadeType.ALL})
public Set<ConnectionInfo> getConnectionInfosForDeployedRelationshipComp()
{
return connectionInfosForDeployedRelationshipComp;
}
}
@Entity
@Table(name = "environment", catalog = "deploy_center", uniqueConstraints = @UniqueConstraint(columnNames = "NAME"))
public class Environment extends AbstractBean
{
private Set<DeployedComponent> deployedComponents = new HashSet<DeployedComponent>( 0 );
/** The installed softwares. */
private Set<InstalledSoftware> installedSoftwares = new HashSet<InstalledSoftware>( 0 );
/** The configuration modelings. */
private Set<ConfigurationModeling> configurationModelings = new HashSet<ConfigurationModeling>( 0 );
/** The selected software options. */
private Set<SelectedSoftwareOption> selectedSoftwareOptions = new HashSet<SelectedSoftwareOption>( 0 );
@OneToMany(fetch = FetchType.LAZY, mappedBy = "environment", orphanRemoval = true)
@org.hibernate.annotations.Cascade({CascadeType.ALL})
public Set<DeployedComponent> getDeployedComponents()
{
return this.deployedComponents;
}
/**
* Gets the deployed components.
* @return the deployed components
*/
@OneToMany(fetch = FetchType.LAZY, mappedBy = "environment", orphanRemoval = true)
@org.hibernate.annotations.Cascade({CascadeType.ALL})
public Set<SelectedSoftwareOption> getSelectedSoftwareOptions()
{
return this.selectedSoftwareOptions;
}
}
private void assessConditionalDependencies( Environment environment, DeployedComponent currentDeployedComponent,
Map<ComponentId, Component> availableComponentsMap, String conditionId, boolean requiredByDependency,
String dependencyCompName, boolean isCompositionDependency )
throws DeploymentCenterServerException, DeploymentCenterValidationException
{
// code snipets
if ( isCompositionDependency && currentDeployedComponent.getMachine() != null
&& DCStringUtils.isNotNullOrEmpty( currentDeployedComponent.getMachine().getHostName() ) )
{
dependentComponents = getCompositionDependencyComponents( environment, currentDeployedComponent, dependencyCompName );
}
else
{
dependentComponents = deployedComponentRepository
.findByObsoletedFalseAndComponentNameAndEnvironmentEnvId( dependencyCompName, environment.getEnvId() );
}
if ( !isDependentComponentNeeded )
{
for ( DeployedComponent toBeDeletedDeployedComponent : dependentComponents )
{
// Delete the component only when it is Pending Install/Pending Mass Client Install
if ( DeploymentStatus.getPendingStatusList().contains( toBeDeletedDeployedComponent.getDeploymentStatus() ) )
{
List<DeployedComponent> componentDependencies = new ArrayList<>();
componentDeletionHandler.populateComponentsToBeRemoved( toBeDeletedDeployedComponent, new ArrayList<>(),
componentDependencies );
for ( DeployedComponent activeDeployedComponent : environment.getActiveDeployedComponents() )
{
Set<ConnectionInfo> connectionInfoToBeRemoved = new HashSet<>();
for ( ConnectionInfo connectionInfo : activeDeployedComponent.getConnectionInfosForDeployedComp() )
{
if ( componentDependencies.contains( connectionInfo.getDeployedComponentByReference() ) )
{
connectionInfoToBeRemoved.add( connectionInfo );
}
}
activeDeployedComponent.getConnectionInfosForDeployedComp().removeAll( connectionInfoToBeRemoved ); //connectionInfoToBeRemoved is blank
}
List<String> componentInfo = componentDependencies.stream()
.map( component -> component.getComponent().getName() ).collect( Collectors.toList() );
LOGGER.info(
"As a condition for component dependency not being met, the following components are removed: ["
+ String.join( DCConstants.COMMA_AND_SPACE, componentInfo ) + "]" );
// environment.getDeployedComponents().removeAll( componentDependencies );
// for( DeployedComponent deployedComponent: componentDependencies) {
// if(deployedComponent.getDeployedComponentId().equals(254L)) {
// componentDependencies.remove(componentDependencies.size()-1);
// }
// }
//componentDependencies.remove(componentDependencies.size()-1);
connectionInfoProvider.removeConnectionInformation(new HashSet<DeployedComponent>(componentDependencies) );
for( DeployedComponent deployedComponent: componentDependencies) {
if(environment.getDeployedComponents().contains(deployedComponent)) {
LOGGER.info("Rahul Components to be remove one by one: "+ deployedComponent);
environment.getDeployedComponents().remove(deployedComponent);
}
}
}
}
}
}
private List<DeployedComponent> getCompositionDependencyComponents( Environment environment,
DeployedComponent currentDeployedComponent, String dependencyCompName )
{
try {
List<DeployedComponent> dependentComponents;
dependentComponents = deployedComponentRepository
.findByObsoletedFalseAndComponentNameAndMachineHostNameIgnoreCaseAndEnvironmentEnvId( dependencyCompName, // this is the real culprit which is giving error
currentDeployedComponent.getMachine().getHostName(), environment.getEnvId() );
if ( dependentComponents.isEmpty() )
{
dependentComponents = deployedComponentRepository
.findByObsoletedFalseAndComponentNameAndMachineHostNameIgnoreCaseAndEnvironmentEnvId( dependencyCompName,
DCConstants.EMPTY_STRING, environment.getEnvId() );
}
return dependentComponents;
}
catch(Exception e) {
e.printStackTrace();
throw e;
}
//return null;
}