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.boot.spi.NaturalIdUniqueKeyBinder;
|
||||||
import org.hibernate.cfg.AnnotatedClassType;
|
import org.hibernate.cfg.AnnotatedClassType;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.CopyIdentifierComponentSecondPass;
|
|
||||||
import org.hibernate.cfg.CreateKeySecondPass;
|
import org.hibernate.cfg.CreateKeySecondPass;
|
||||||
import org.hibernate.cfg.FkSecondPass;
|
import org.hibernate.cfg.FkSecondPass;
|
||||||
import org.hibernate.cfg.IdGeneratorResolverSecondPass;
|
import org.hibernate.cfg.IdGeneratorResolverSecondPass;
|
||||||
|
@ -1504,7 +1503,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
||||||
|
|
||||||
private ArrayList<IdGeneratorResolverSecondPass> idGeneratorResolverSecondPassList;
|
private ArrayList<IdGeneratorResolverSecondPass> idGeneratorResolverSecondPassList;
|
||||||
private ArrayList<SetSimpleValueTypeSecondPass> setSimpleValueTypeSecondPassList;
|
private ArrayList<SetSimpleValueTypeSecondPass> setSimpleValueTypeSecondPassList;
|
||||||
private ArrayList<CopyIdentifierComponentSecondPass> copyIdentifierComponentSecondPasList;
|
|
||||||
private ArrayList<FkSecondPass> fkSecondPassList;
|
private ArrayList<FkSecondPass> fkSecondPassList;
|
||||||
private ArrayList<CreateKeySecondPass> createKeySecondPasList;
|
private ArrayList<CreateKeySecondPass> createKeySecondPasList;
|
||||||
private ArrayList<SecondaryTableSecondPass> secondaryTableSecondPassList;
|
private ArrayList<SecondaryTableSecondPass> secondaryTableSecondPassList;
|
||||||
|
@ -1526,9 +1524,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
||||||
else if ( secondPass instanceof SetSimpleValueTypeSecondPass ) {
|
else if ( secondPass instanceof SetSimpleValueTypeSecondPass ) {
|
||||||
addSetSimpleValueTypeSecondPass( (SetSimpleValueTypeSecondPass) secondPass, onTopOfTheQueue );
|
addSetSimpleValueTypeSecondPass( (SetSimpleValueTypeSecondPass) secondPass, onTopOfTheQueue );
|
||||||
}
|
}
|
||||||
else if ( secondPass instanceof CopyIdentifierComponentSecondPass ) {
|
|
||||||
addCopyIdentifierComponentSecondPass( (CopyIdentifierComponentSecondPass) secondPass, onTopOfTheQueue );
|
|
||||||
}
|
|
||||||
else if ( secondPass instanceof FkSecondPass ) {
|
else if ( secondPass instanceof FkSecondPass ) {
|
||||||
addFkSecondPass( (FkSecondPass) secondPass, onTopOfTheQueue );
|
addFkSecondPass( (FkSecondPass) secondPass, onTopOfTheQueue );
|
||||||
}
|
}
|
||||||
|
@ -1576,15 +1571,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
||||||
addSecondPass( secondPass, idGeneratorResolverSecondPassList, onTopOfTheQueue );
|
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) {
|
private void addFkSecondPass(FkSecondPass secondPass, boolean onTopOfTheQueue) {
|
||||||
if ( fkSecondPassList == null ) {
|
if ( fkSecondPassList == null ) {
|
||||||
fkSecondPassList = new ArrayList<>();
|
fkSecondPassList = new ArrayList<>();
|
||||||
|
@ -1635,8 +1621,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
||||||
processSecondPasses( implicitColumnNamingSecondPassList );
|
processSecondPasses( implicitColumnNamingSecondPassList );
|
||||||
processSecondPasses( setSimpleValueTypeSecondPassList );
|
processSecondPasses( setSimpleValueTypeSecondPassList );
|
||||||
|
|
||||||
processCopyIdentifierSecondPassesInOrder();
|
|
||||||
|
|
||||||
processFkSecondPassesInOrder();
|
processFkSecondPassesInOrder();
|
||||||
|
|
||||||
processSecondPasses( createKeySecondPasList );
|
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) {
|
private void processSecondPasses(ArrayList<? extends SecondPass> secondPasses) {
|
||||||
if ( secondPasses == null ) {
|
if ( secondPasses == null ) {
|
||||||
return;
|
return;
|
||||||
|
@ -1681,39 +1657,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
||||||
secondPasses.clear();
|
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() {
|
private void processFkSecondPassesInOrder() {
|
||||||
if ( fkSecondPassList == null || fkSecondPassList.isEmpty() ) {
|
if ( fkSecondPassList == null || fkSecondPassList.isEmpty() ) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -16,8 +16,6 @@ import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.boot.model.naming.Identifier;
|
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.naming.PhysicalNamingStrategy;
|
||||||
import org.hibernate.boot.model.relational.Database;
|
import org.hibernate.boot.model.relational.Database;
|
||||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
|
@ -33,7 +31,7 @@ import org.jboss.logging.Logger;
|
||||||
/**
|
/**
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
public class CopyIdentifierComponentSecondPass implements SecondPass {
|
public class CopyIdentifierComponentSecondPass extends FkSecondPass {
|
||||||
private static final Logger log = Logger.getLogger( CopyIdentifierComponentSecondPass.class );
|
private static final Logger log = Logger.getLogger( CopyIdentifierComponentSecondPass.class );
|
||||||
|
|
||||||
private final String referencedEntityName;
|
private final String referencedEntityName;
|
||||||
|
@ -46,12 +44,25 @@ public class CopyIdentifierComponentSecondPass implements SecondPass {
|
||||||
String referencedEntityName,
|
String referencedEntityName,
|
||||||
Ejb3JoinColumn[] joinColumns,
|
Ejb3JoinColumn[] joinColumns,
|
||||||
MetadataBuildingContext buildingContext) {
|
MetadataBuildingContext buildingContext) {
|
||||||
|
super( comp, joinColumns );
|
||||||
this.component = comp;
|
this.component = comp;
|
||||||
this.referencedEntityName = referencedEntityName;
|
this.referencedEntityName = referencedEntityName;
|
||||||
this.buildingContext = buildingContext;
|
this.buildingContext = buildingContext;
|
||||||
this.joinColumns = joinColumns;
|
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" })
|
@SuppressWarnings({ "unchecked" })
|
||||||
public void doSecondPass(Map persistentClasses) throws MappingException {
|
public void doSecondPass(Map persistentClasses) throws MappingException {
|
||||||
PersistentClass referencedPersistentClass = (PersistentClass) persistentClasses.get( referencedEntityName );
|
PersistentClass referencedPersistentClass = (PersistentClass) persistentClasses.get( referencedEntityName );
|
||||||
|
@ -219,8 +230,4 @@ public class CopyIdentifierComponentSecondPass implements SecondPass {
|
||||||
mappingColumn.setPrecision( column.getPrecision() );
|
mappingColumn.setPrecision( column.getPrecision() );
|
||||||
mappingColumn.setScale( column.getScale() );
|
mappingColumn.setScale( column.getScale() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean dependentUpon( CopyIdentifierComponentSecondPass other ) {
|
|
||||||
return this.referencedEntityName.equals( other.component.getOwner().getEntityName() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue