fix issue with circularity detection
This commit is contained in:
parent
1df4824d5f
commit
90cd4e5c8f
|
@ -13,10 +13,4 @@ import org.hibernate.sql.results.graph.Fetchable;
|
||||||
*/
|
*/
|
||||||
public interface Association extends Fetchable {
|
public interface Association extends Fetchable {
|
||||||
ForeignKeyDescriptor getForeignKeyDescriptor();
|
ForeignKeyDescriptor getForeignKeyDescriptor();
|
||||||
|
|
||||||
/**
|
|
||||||
* The column expressions that identify this association.
|
|
||||||
* Mainly used in circularity detection
|
|
||||||
*/
|
|
||||||
String[] getIdentifyingColumnExpressions();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,6 @@ public class EntityCollectionPart
|
||||||
private final EntityMappingType entityMappingType;
|
private final EntityMappingType entityMappingType;
|
||||||
|
|
||||||
private ModelPart fkTargetModelPart;
|
private ModelPart fkTargetModelPart;
|
||||||
private String[] identifyingColumns;
|
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public EntityCollectionPart(
|
public EntityCollectionPart(
|
||||||
|
@ -75,14 +74,6 @@ public class EntityCollectionPart
|
||||||
else {
|
else {
|
||||||
fkTargetModelPart = entityMappingType.findSubPart( fkTargetModelPartName, null );
|
fkTargetModelPart = entityMappingType.findSubPart( fkTargetModelPartName, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<String> identifyingColumnsList = new ArrayList<>();
|
|
||||||
collectionDescriptor.getAttributeMapping().getKeyDescriptor().visitReferringColumns(
|
|
||||||
(containingTableExpression, columnExpression, jdbcMapping) -> {
|
|
||||||
identifyingColumnsList.add( containingTableExpression + "." + columnExpression );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.identifyingColumns = identifyingColumnsList.toArray( new String[0] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -212,9 +203,4 @@ public class EntityCollectionPart
|
||||||
// todo (6.0) : this will not strictly work - we'd want a new ForeignKeyDescriptor that points the other direction
|
// todo (6.0) : this will not strictly work - we'd want a new ForeignKeyDescriptor that points the other direction
|
||||||
return collectionDescriptor.getAttributeMapping().getKeyDescriptor();
|
return collectionDescriptor.getAttributeMapping().getKeyDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getIdentifyingColumnExpressions() {
|
|
||||||
return identifyingColumns;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
@ -57,6 +58,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
||||||
private final String targetColumnExpression;
|
private final String targetColumnExpression;
|
||||||
private final JdbcMapping jdbcMapping;
|
private final JdbcMapping jdbcMapping;
|
||||||
private final ForeignKeyDirection fKeyDirection;
|
private final ForeignKeyDirection fKeyDirection;
|
||||||
|
private final int hasCode;
|
||||||
|
|
||||||
public SimpleForeignKeyDescriptor(
|
public SimpleForeignKeyDescriptor(
|
||||||
ForeignKeyDirection fKeyDirection,
|
ForeignKeyDirection fKeyDirection,
|
||||||
|
@ -71,6 +73,13 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
||||||
this.targetColumnContainingTable = targetColumnContainingTable;
|
this.targetColumnContainingTable = targetColumnContainingTable;
|
||||||
this.targetColumnExpression = targetColumnExpression;
|
this.targetColumnExpression = targetColumnExpression;
|
||||||
this.jdbcMapping = jdbcMapping;
|
this.jdbcMapping = jdbcMapping;
|
||||||
|
|
||||||
|
this.hasCode = Objects.hash(
|
||||||
|
keyColumnContainingTable,
|
||||||
|
keyColumnExpression,
|
||||||
|
targetColumnContainingTable,
|
||||||
|
targetColumnExpression
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -405,4 +414,24 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
||||||
public String getTargetColumnExpression() {
|
public String getTargetColumnExpression() {
|
||||||
return targetColumnExpression;
|
return targetColumnExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( o == null || getClass() != o.getClass() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SimpleForeignKeyDescriptor that = (SimpleForeignKeyDescriptor) o;
|
||||||
|
return Objects.equals( keyColumnContainingTable, that.keyColumnContainingTable ) &&
|
||||||
|
Objects.equals( targetColumnContainingTable, that.targetColumnContainingTable ) &&
|
||||||
|
Objects.equals( keyColumnExpression, that.keyColumnExpression ) &&
|
||||||
|
Objects.equals( targetColumnExpression, that.targetColumnExpression );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.hasCode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.mapping.internal;
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
|
@ -81,11 +77,6 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
|
||||||
|
|
||||||
private ForeignKeyDescriptor foreignKeyDescriptor;
|
private ForeignKeyDescriptor foreignKeyDescriptor;
|
||||||
private String identifyingColumnsTableExpression;
|
private String identifyingColumnsTableExpression;
|
||||||
private String inverseIdentifyingColumnsTableExpression;
|
|
||||||
private String[] identifyingColumns;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public SingularAssociationAttributeMapping(
|
public SingularAssociationAttributeMapping(
|
||||||
String name,
|
String name,
|
||||||
|
@ -139,30 +130,14 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
|
||||||
this.foreignKeyDescriptor = foreignKeyDescriptor;
|
this.foreignKeyDescriptor = foreignKeyDescriptor;
|
||||||
|
|
||||||
final String identifyingColumnsTableExpression;
|
final String identifyingColumnsTableExpression;
|
||||||
final String inverseColumnsTableExpression;
|
|
||||||
final List<String> identifyingColumnsList = new ArrayList<>();
|
|
||||||
if ( foreignKeyDescriptor.getDirection() == ForeignKeyDirection.FROM_PARENT && !referringPrimaryKey ) {
|
if ( foreignKeyDescriptor.getDirection() == ForeignKeyDirection.FROM_PARENT && !referringPrimaryKey ) {
|
||||||
identifyingColumnsTableExpression = foreignKeyDescriptor.getTargetTableExpression();
|
identifyingColumnsTableExpression = foreignKeyDescriptor.getTargetTableExpression();
|
||||||
inverseColumnsTableExpression = foreignKeyDescriptor.getReferringTableExpression();
|
|
||||||
foreignKeyDescriptor.visitTargetColumns(
|
|
||||||
(containingTableExpression, columnExpression, jdbcMapping) -> {
|
|
||||||
identifyingColumnsList.add( containingTableExpression + "." + columnExpression );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
identifyingColumnsTableExpression = foreignKeyDescriptor.getReferringTableExpression();
|
identifyingColumnsTableExpression = foreignKeyDescriptor.getReferringTableExpression();
|
||||||
inverseColumnsTableExpression = foreignKeyDescriptor.getTargetTableExpression();
|
|
||||||
foreignKeyDescriptor.visitReferringColumns(
|
|
||||||
(containingTableExpression, columnExpression, jdbcMapping) -> {
|
|
||||||
identifyingColumnsList.add( containingTableExpression + "." + columnExpression );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.identifyingColumns = identifyingColumnsList.toArray( new String[0] );
|
|
||||||
this.identifyingColumnsTableExpression = identifyingColumnsTableExpression;
|
this.identifyingColumnsTableExpression = identifyingColumnsTableExpression;
|
||||||
this.inverseIdentifyingColumnsTableExpression = inverseColumnsTableExpression;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ForeignKeyDescriptor getForeignKeyDescriptor() {
|
public ForeignKeyDescriptor getForeignKeyDescriptor() {
|
||||||
|
@ -188,11 +163,6 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
|
||||||
return navigableRole;
|
return navigableRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getIdentifyingColumnExpressions() {
|
|
||||||
return identifyingColumns;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fetch resolveCircularFetch(
|
public Fetch resolveCircularFetch(
|
||||||
NavigablePath fetchablePath,
|
NavigablePath fetchablePath,
|
||||||
|
@ -218,7 +188,7 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
|
||||||
|
|
||||||
final Association associationParent = (Association) referencedModePart;
|
final Association associationParent = (Association) referencedModePart;
|
||||||
|
|
||||||
if ( Arrays.equals( associationParent.getIdentifyingColumnExpressions(), this.getIdentifyingColumnExpressions() ) ) {
|
if (foreignKeyDescriptor.equals( associationParent.getForeignKeyDescriptor() ) ) {
|
||||||
// we need to determine the NavigablePath referring to the entity that the bi-dir
|
// we need to determine the NavigablePath referring to the entity that the bi-dir
|
||||||
// fetch will "return" for its Assembler. so we walk "up" the FetchParent graph
|
// fetch will "return" for its Assembler. so we walk "up" the FetchParent graph
|
||||||
// to find the "referenced entity" reference
|
// to find the "referenced entity" reference
|
||||||
|
|
|
@ -52,14 +52,22 @@ public class Helper {
|
||||||
if ( ResultsLogger.INSTANCE.isDebugEnabled() ) {
|
if ( ResultsLogger.INSTANCE.isDebugEnabled() ) {
|
||||||
return initializer -> {
|
return initializer -> {
|
||||||
ResultsLogger.INSTANCE.debug( "Adding initializer : " + initializer );
|
ResultsLogger.INSTANCE.debug( "Adding initializer : " + initializer );
|
||||||
initializers.add( initializer );
|
addIfNotPresent( initializers, initializer );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return initializers::add;
|
return initializer ->
|
||||||
|
addIfNotPresent( initializers, initializer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void addIfNotPresent(List<Initializer> initializers, Initializer initializer) {
|
||||||
|
if ( initializers.contains( initializer ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
initializers.add( initializer );
|
||||||
|
}
|
||||||
|
|
||||||
public static void finalizeCollectionLoading(
|
public static void finalizeCollectionLoading(
|
||||||
PersistenceContext persistenceContext,
|
PersistenceContext persistenceContext,
|
||||||
CollectionPersister collectionDescriptor,
|
CollectionPersister collectionDescriptor,
|
||||||
|
|
|
@ -155,13 +155,6 @@ public class BiDirectionalFetchImpl implements BiDirectionalFetch, Association {
|
||||||
return ( (Association) fetchParent ).getForeignKeyDescriptor();
|
return ( (Association) fetchParent ).getForeignKeyDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getIdentifyingColumnExpressions() {
|
|
||||||
// fetch parent really always needs to be an Association, so we simply cast here
|
|
||||||
// should maybe verify this in ctor
|
|
||||||
return ( (Association) fetchParent ).getIdentifyingColumnExpressions();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Fetch generateFetch(
|
public Fetch generateFetch(
|
||||||
FetchParent fetchParent,
|
FetchParent fetchParent,
|
||||||
|
|
Loading…
Reference in New Issue