Skip to content

Commit

Permalink
HHH-14918 Always process components containing an ID copy as we would…
Browse files Browse the repository at this point in the history
… any other FK
  • Loading branch information
yrodiere committed Nov 8, 2021
1 parent 6c53a9d commit ccd58ee
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 64 deletions.
Expand Up @@ -57,7 +57,6 @@
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;
Expand Down Expand Up @@ -1504,7 +1503,6 @@ public Join locateJoin(Identifier tableName) {

private ArrayList<IdGeneratorResolverSecondPass> idGeneratorResolverSecondPassList;
private ArrayList<SetSimpleValueTypeSecondPass> setSimpleValueTypeSecondPassList;
private ArrayList<CopyIdentifierComponentSecondPass> copyIdentifierComponentSecondPasList;
private ArrayList<FkSecondPass> fkSecondPassList;
private ArrayList<CreateKeySecondPass> createKeySecondPasList;
private ArrayList<SecondaryTableSecondPass> secondaryTableSecondPassList;
Expand All @@ -1526,9 +1524,6 @@ public void addSecondPass(SecondPass secondPass, boolean onTopOfTheQueue) {
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 );
}
Expand Down Expand Up @@ -1576,15 +1571,6 @@ private void addIdGeneratorResolverSecondPass(IdGeneratorResolverSecondPass seco
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<>();
Expand Down Expand Up @@ -1635,8 +1621,6 @@ public void processSecondPasses(MetadataBuildingContext buildingContext) {
processSecondPasses( implicitColumnNamingSecondPassList );
processSecondPasses( setSimpleValueTypeSecondPassList );

processCopyIdentifierSecondPassesInOrder();

processFkSecondPassesInOrder();

processSecondPasses( createKeySecondPasList );
Expand All @@ -1661,14 +1645,6 @@ public void processSecondPasses(MetadataBuildingContext buildingContext) {
}
}

private void processCopyIdentifierSecondPassesInOrder() {
if ( copyIdentifierComponentSecondPasList == null ) {
return;
}
sortCopyIdentifierComponentSecondPasses();
processSecondPasses( copyIdentifierComponentSecondPasList );
}

private void processSecondPasses(ArrayList<? extends SecondPass> secondPasses) {
if ( secondPasses == null ) {
return;
Expand All @@ -1681,39 +1657,6 @@ private void processSecondPasses(ArrayList<? extends SecondPass> secondPasses) {
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;
Expand Down
Expand Up @@ -16,8 +16,6 @@
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;
Expand All @@ -33,7 +31,7 @@
/**
* @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;
Expand All @@ -46,12 +44,25 @@ public CopyIdentifierComponentSecondPass(
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 );
Expand Down Expand Up @@ -219,8 +230,4 @@ private void applyComponentColumnSizeValueToJoinColumn(Column column, Ejb3JoinCo
mappingColumn.setPrecision( column.getPrecision() );
mappingColumn.setScale( column.getScale() );
}

public boolean dependentUpon( CopyIdentifierComponentSecondPass other ) {
return this.referencedEntityName.equals( other.component.getOwner().getEntityName() );
}
}

0 comments on commit ccd58ee

Please sign in to comment.