HHH-14918 Always process components containing an ID copy as we would any other FK
This commit is contained in:
parent
6c53a9d1ab
commit
ccd58ee499
|
@ -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;
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue