HHH-14918 Always process components containing an ID copy as we would any other FK

This commit is contained in:
Yoann Rodière 2021-11-08 13:28:44 +01:00
parent 6c53a9d1ab
commit ccd58ee499
2 changed files with 14 additions and 64 deletions

View File

@ -57,7 +57,6 @@ import org.hibernate.boot.spi.MetadataBuildingOptions;
import org.hibernate.boot.spi.NaturalIdUniqueKeyBinder;
import org.hibernate.cfg.AnnotatedClassType;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.CopyIdentifierComponentSecondPass;
import org.hibernate.cfg.CreateKeySecondPass;
import org.hibernate.cfg.FkSecondPass;
import org.hibernate.cfg.IdGeneratorResolverSecondPass;
@ -1504,7 +1503,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
private ArrayList<IdGeneratorResolverSecondPass> idGeneratorResolverSecondPassList;
private ArrayList<SetSimpleValueTypeSecondPass> setSimpleValueTypeSecondPassList;
private ArrayList<CopyIdentifierComponentSecondPass> copyIdentifierComponentSecondPasList;
private ArrayList<FkSecondPass> fkSecondPassList;
private ArrayList<CreateKeySecondPass> createKeySecondPasList;
private ArrayList<SecondaryTableSecondPass> secondaryTableSecondPassList;
@ -1526,9 +1524,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
else if ( secondPass instanceof SetSimpleValueTypeSecondPass ) {
addSetSimpleValueTypeSecondPass( (SetSimpleValueTypeSecondPass) secondPass, onTopOfTheQueue );
}
else if ( secondPass instanceof CopyIdentifierComponentSecondPass ) {
addCopyIdentifierComponentSecondPass( (CopyIdentifierComponentSecondPass) secondPass, onTopOfTheQueue );
}
else if ( secondPass instanceof FkSecondPass ) {
addFkSecondPass( (FkSecondPass) secondPass, onTopOfTheQueue );
}
@ -1576,15 +1571,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
addSecondPass( secondPass, idGeneratorResolverSecondPassList, onTopOfTheQueue );
}
private void addCopyIdentifierComponentSecondPass(
CopyIdentifierComponentSecondPass secondPass,
boolean onTopOfTheQueue) {
if ( copyIdentifierComponentSecondPasList == null ) {
copyIdentifierComponentSecondPasList = new ArrayList<>();
}
addSecondPass( secondPass, copyIdentifierComponentSecondPasList, onTopOfTheQueue );
}
private void addFkSecondPass(FkSecondPass secondPass, boolean onTopOfTheQueue) {
if ( fkSecondPassList == null ) {
fkSecondPassList = new ArrayList<>();
@ -1635,8 +1621,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
processSecondPasses( implicitColumnNamingSecondPassList );
processSecondPasses( setSimpleValueTypeSecondPassList );
processCopyIdentifierSecondPassesInOrder();
processFkSecondPassesInOrder();
processSecondPasses( createKeySecondPasList );
@ -1661,14 +1645,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
}
}
private void processCopyIdentifierSecondPassesInOrder() {
if ( copyIdentifierComponentSecondPasList == null ) {
return;
}
sortCopyIdentifierComponentSecondPasses();
processSecondPasses( copyIdentifierComponentSecondPasList );
}
private void processSecondPasses(ArrayList<? extends SecondPass> secondPasses) {
if ( secondPasses == null ) {
return;
@ -1681,39 +1657,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
secondPasses.clear();
}
private void sortCopyIdentifierComponentSecondPasses() {
ArrayList<CopyIdentifierComponentSecondPass> sorted =
new ArrayList<>( copyIdentifierComponentSecondPasList.size() );
Set<CopyIdentifierComponentSecondPass> toSort = new HashSet<>( copyIdentifierComponentSecondPasList );
topologicalSort( sorted, toSort );
copyIdentifierComponentSecondPasList = sorted;
}
/* naive O(n^3) topological sort */
private void topologicalSort( List<CopyIdentifierComponentSecondPass> sorted, Set<CopyIdentifierComponentSecondPass> toSort ) {
while (!toSort.isEmpty()) {
CopyIdentifierComponentSecondPass independent = null;
searchForIndependent:
for ( CopyIdentifierComponentSecondPass secondPass : toSort ) {
for ( CopyIdentifierComponentSecondPass other : toSort ) {
if (secondPass.dependentUpon( other )) {
continue searchForIndependent;
}
}
independent = secondPass;
break;
}
if (independent == null) {
throw new MappingException( "cyclic dependency in derived identities" );
}
toSort.remove( independent );
sorted.add( independent );
}
}
private void processFkSecondPassesInOrder() {
if ( fkSecondPassList == null || fkSecondPassList.isEmpty() ) {
return;

View File

@ -16,8 +16,6 @@ import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.MappingException;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
import org.hibernate.boot.model.naming.ObjectNameNormalizer;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.spi.MetadataBuildingContext;
@ -33,7 +31,7 @@ import org.jboss.logging.Logger;
/**
* @author Emmanuel Bernard
*/
public class CopyIdentifierComponentSecondPass implements SecondPass {
public class CopyIdentifierComponentSecondPass extends FkSecondPass {
private static final Logger log = Logger.getLogger( CopyIdentifierComponentSecondPass.class );
private final String referencedEntityName;
@ -46,12 +44,25 @@ public class CopyIdentifierComponentSecondPass implements SecondPass {
String referencedEntityName,
Ejb3JoinColumn[] joinColumns,
MetadataBuildingContext buildingContext) {
super( comp, joinColumns );
this.component = comp;
this.referencedEntityName = referencedEntityName;
this.buildingContext = buildingContext;
this.joinColumns = joinColumns;
}
@Override
public String getReferencedEntityName() {
return referencedEntityName;
}
@Override
public boolean isInPrimaryKey() {
// This second pass is apparently only ever used to initialize composite identifiers
return true;
}
@Override
@SuppressWarnings({ "unchecked" })
public void doSecondPass(Map persistentClasses) throws MappingException {
PersistentClass referencedPersistentClass = (PersistentClass) persistentClasses.get( referencedEntityName );
@ -219,8 +230,4 @@ public class CopyIdentifierComponentSecondPass implements SecondPass {
mappingColumn.setPrecision( column.getPrecision() );
mappingColumn.setScale( column.getScale() );
}
public boolean dependentUpon( CopyIdentifierComponentSecondPass other ) {
return this.referencedEntityName.equals( other.component.getOwner().getEntityName() );
}
}