ToOneAttibuteMapping, Do not consider the referencedPropertyName for the bidirectionalAttributeName determination

This commit is contained in:
Andrea Boriero 2020-06-29 16:43:24 +01:00
parent 3c7a208b96
commit 468989a0f3
7 changed files with 81 additions and 51 deletions

View File

@ -432,8 +432,6 @@ public class LoaderSelectBuilder {
}
final List<Fetch> fetches = new ArrayList<>();
String fullPath = fetchParent.getNavigablePath().getFullPath();
final BiConsumer<Fetchable, Boolean> processor = createFetchableBiConsumer( fetchParent, querySpec, creationState, fetches );
final FetchableContainer referencedMappingContainer = fetchParent.getReferencedMappingContainer();

View File

@ -11,6 +11,7 @@ import java.util.function.Consumer;
import org.hibernate.loader.ast.spi.Loadable;
import org.hibernate.metamodel.mapping.ordering.OrderByFragment;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
@ -56,5 +57,5 @@ public interface PluralAttributeMapping
String getSeparateCollectionTable();
String getBidirectionalPropertyName();
boolean isBidirectionalAttributeName(NavigablePath fetchablePath);
}

View File

@ -98,7 +98,8 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
private final FetchStyle fetchStyle;
private final CascadeStyle cascadeStyle;
private final String bidirectionalPropertyName;
private final String bidirectionalAttributeName;
private final Boolean isInverse;
private final CollectionPersister collectionDescriptor;
private final String separateCollectionTable;
@ -175,7 +176,9 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
this.cascadeStyle = cascadeStyle;
this.collectionDescriptor = collectionDescriptor;
this.bidirectionalPropertyName = StringHelper.subStringNullIfEmpty( bootDescriptor.getMappedByProperty(), '.');
this.bidirectionalAttributeName = StringHelper.subStringNullIfEmpty( bootDescriptor.getMappedByProperty(), '.');
this.isInverse = bootDescriptor.isInverse();
this.sqlAliasStem = SqlAliasStemHelper.INSTANCE.generateStemFromAttributeName( attributeName );
@ -222,6 +225,17 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
}
}
@Override
public boolean isBidirectionalAttributeName(NavigablePath fetchablePath) {
if ( isInverse ) {
return true;
}
if ( bidirectionalAttributeName == null ) {
return false;
}
return fetchablePath.getFullPath().endsWith( bidirectionalAttributeName );
}
@SuppressWarnings("unused")
public void finishInitialization(
Property bootProperty,
@ -393,11 +407,6 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
return separateCollectionTable;
}
@Override
public String getBidirectionalPropertyName() {
return bidirectionalPropertyName;
}
@Override
public int getStateArrayPosition() {
return stateArrayPosition;

View File

@ -76,7 +76,7 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
private final boolean referringPrimaryKey;
private final Cardinality cardinality;
private String bidirectionalPropertyName;
private String bidirectionalAttributeName;
private ForeignKeyDescriptor foreignKeyDescriptor;
private ForeignKeyDirection foreignKeyDirection;
@ -170,18 +170,11 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
the the navigable path is NavigablePath(Card.fields.{element}.{id}.card) and it does not contain the "primaryKey" part
so in ored to recognize the bidirectionality the "primaryKey." is removed from the otherSidePropertyName value.
*/
String mappedByProperty = StringHelper.subStringNullIfEmpty(
// todo (6.0): find a better solution for the embeddable part name not in the NavigablePath
bidirectionalAttributeName = StringHelper.subStringNullIfEmpty(
( (OneToOne) bootValue ).getMappedByProperty(),
'.'
);
if ( mappedByProperty == null ) {
bidirectionalPropertyName = StringHelper.subStringNullIfEmpty( referencedPropertyName, '.' );
}
else {
bidirectionalPropertyName = mappedByProperty;
}
}
this.navigableRole = navigableRole;
@ -230,19 +223,19 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
final AssociationKey associationKey = foreignKeyDescriptor.getAssociationKey();
if ( creationState.isAssociationKeyVisited( associationKey ) ) {
NavigablePath parent = fetchablePath.getParent();
ModelPart modelPart = creationState.resolveModelPart( parent );
NavigablePath parentNavigablePath = fetchablePath.getParent();
ModelPart modelPart = creationState.resolveModelPart( parentNavigablePath );
if ( modelPart instanceof EmbeddedIdentifierMappingImpl ) {
while ( parent.getFullPath().endsWith( EntityIdentifierMapping.ROLE_LOCAL_NAME ) ) {
parent = parent.getParent();
while ( parentNavigablePath.getFullPath().endsWith( EntityIdentifierMapping.ROLE_LOCAL_NAME ) ) {
parentNavigablePath = parentNavigablePath.getParent();
}
}
while ( modelPart instanceof EmbeddableValuedFetchable ) {
parent = parent.getParent();
modelPart = creationState.resolveModelPart( parent );
parentNavigablePath = parentNavigablePath.getParent();
modelPart = creationState.resolveModelPart( parentNavigablePath );
}
if ( this.bidirectionalPropertyName != null && parent.getFullPath().endsWith( this.bidirectionalPropertyName ) ) {
if ( isBidirectionalAttributeName( parentNavigablePath ) ) {
/*
class Child {
@OneToOne(mappedBy = "biologicalChild")
@ -261,7 +254,7 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
return createCircularBiDirectionalFetch(
fetchablePath,
fetchParent,
parent.getParent(),
parentNavigablePath,
LockMode.READ
);
}
@ -269,8 +262,13 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
/*
check if mappedBy is on the other side of the association
*/
final String otherSideMappedBy = getOthrerSideMappedBy( modelPart, parent.getParent(), creationState );
if ( otherSideMappedBy != null ) {
final boolean isBiDirectional = isBidirectional(
modelPart,
parentNavigablePath.getParent(),
fetchablePath,
creationState
);
if ( isBiDirectional ) {
/*
class Child {
@OneToOne(mappedBy = "biologicalChild")
@ -287,15 +285,12 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
otherSideMappedBy = "biologicalChild"
*/
if ( fetchablePath.getFullPath().endsWith( otherSideMappedBy ) ) {
return createCircularBiDirectionalFetch(
fetchablePath,
fetchParent,
parent.getParent(),
LockMode.READ
);
}
return createCircularBiDirectionalFetch(
fetchablePath,
fetchParent,
parentNavigablePath,
LockMode.READ
);
}
/*
class Child {
@ -329,37 +324,53 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
return null;
}
private String getOthrerSideMappedBy(
private boolean isBidirectional(
ModelPart modelPart,
NavigablePath parentOfParent,
NavigablePath fetchablePath,
DomainResultCreationState creationState) {
if ( modelPart instanceof ToOneAttributeMapping ) {
return ( (ToOneAttributeMapping) modelPart ).getBidirectionalPropertyName();
return ( (ToOneAttributeMapping) modelPart ).isBidirectionalAttributeName( fetchablePath );
}
if ( modelPart instanceof PluralAttributeMapping ) {
return ( (PluralAttributeMapping) modelPart ).getBidirectionalPropertyName();
return ( (PluralAttributeMapping) modelPart ).isBidirectionalAttributeName( fetchablePath );
}
if ( modelPart instanceof EntityCollectionPart ) {
if ( parentOfParent.getFullPath().endsWith( EntityIdentifierMapping.ROLE_LOCAL_NAME ) ) {
parentOfParent = parentOfParent.getParent();
}
return ( (PluralAttributeMapping) creationState.resolveModelPart( parentOfParent ) ).getBidirectionalPropertyName();
return ( (PluralAttributeMapping) creationState.resolveModelPart( parentOfParent ) ).isBidirectionalAttributeName(
fetchablePath );
}
return null;
return false;
}
public String getBidirectionalPropertyName(){
return bidirectionalPropertyName;
protected boolean isBidirectionalAttributeName(NavigablePath fetchablePath) {
if ( bidirectionalAttributeName == null ) {
return false;
}
return fetchablePath.getFullPath().endsWith( bidirectionalAttributeName );
}
public String getBidirectionalAttributeName(){
return bidirectionalAttributeName;
}
private Fetch createCircularBiDirectionalFetch(
NavigablePath fetchablePath,
FetchParent fetchParent,
NavigablePath referencedNavigablePath,
NavigablePath parentNavigablePath,
LockMode lockMode) {
NavigablePath referencedNavigablePath;
if ( parentNavigablePath.getParent() == null ) {
referencedNavigablePath = parentNavigablePath;
}
else {
referencedNavigablePath = parentNavigablePath.getParent();
}
return new CircularBiDirectionalFetchImpl(
FetchTiming.IMMEDIATE,
fetchablePath,

View File

@ -531,10 +531,10 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
if ( persistentClass.isPolymorphic() ) {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
int initialCapacity = subclassSpan + 1;
final int initialCapacity = CollectionHelper.determineProperSizing( subclassSpan + 1 );
discriminatorValuesByTableName = new LinkedHashMap<>( initialCapacity );
discriminatorColumnNameByTableName = new LinkedHashMap<>( initialCapacity );
subclassNameByTableName = CollectionHelper.mapOfSize( initialCapacity );
subclassNameByTableName = new HashMap<>( initialCapacity );
// We need to convert the `discriminatorSQLString` (which is a String read from boot-mapping) into
// the type indicated by `#discriminatorType` (String -> Integer, e.g.).
try {

View File

@ -43,7 +43,7 @@ public class EntitySelectFetchByUniqueKeyInitializer extends EntitySelectFetchIn
return;
}
final String entityName = concreteDescriptor.getEntityName();
String uniqueKeyPropertyName = fetchedAttribute.getBidirectionalPropertyName();
String uniqueKeyPropertyName = fetchedAttribute.getBidirectionalAttributeName();
final SharedSessionContractImplementor session = rowProcessingState.getSession();

View File

@ -15,6 +15,7 @@ import org.hibernate.sql.results.LoadingLogger;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.Initializer;
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
import org.hibernate.sql.results.graph.entity.internal.EntityDelayedFetchInitializer;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingState;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
@ -155,7 +156,17 @@ public class StandardRowReader<T> implements RowReader<T> {
}
for ( int i = 0; i < numberOfInitializers; i++ ) {
initializers.get( i ).resolveInstance( rowProcessingState );
Initializer initializer = initializers.get( i );
if ( !( initializer instanceof EntityDelayedFetchInitializer ) ) {
initializer.resolveInstance( rowProcessingState );
}
}
for ( int i = 0; i < numberOfInitializers; i++ ) {
Initializer initializer = initializers.get( i );
if ( initializer instanceof EntityDelayedFetchInitializer ) {
initializer.resolveInstance( rowProcessingState );
}
}
for ( int i = 0; i < numberOfInitializers; i++ ) {