Search in sources :

Example 1 with CircularFetchImpl

use of org.hibernate.sql.results.internal.domain.CircularFetchImpl in project hibernate-orm by hibernate.

the class ToOneAttributeMapping method resolveCircularFetch.

@Override
public Fetch resolveCircularFetch(NavigablePath fetchablePath, FetchParent fetchParent, FetchTiming fetchTiming, DomainResultCreationState creationState) {
    final AssociationKey associationKey = foreignKeyDescriptor.getAssociationKey();
    if (creationState.isAssociationKeyVisited(associationKey) || bidirectionalAttributeName != null && !creationState.isRegisteringVisitedAssociationKeys()) {
        NavigablePath parentNavigablePath = fetchablePath.getParent();
        assert parentNavigablePath.equals(fetchParent.getNavigablePath());
        /*
				@Entity
				public class Card {
					@Id
					private String id;
					@ManyToOne
					private CardField field;
				}
				@Entity
				public class CardField {
					@EmbeddedId
					private PrimaryKey primaryKey;
				}
				@Embeddable
				public class PrimaryKey {
					@ManyToOne(optional = false)
					private Card card;
					@ManyToOne(optional = false)
					private Key key;
				}
			 */
        if (parentNavigablePath.getLocalName().equals(ForeignKeyDescriptor.PART_NAME)) {
            // todo (6.0): maybe it's better to have a flag in creation state that marks if we are building a circular fetch domain result already to skip this?
            return null;
        }
        ModelPart parentModelPart = creationState.resolveModelPart(parentNavigablePath);
        if (parentModelPart instanceof EmbeddedIdentifierMappingImpl) {
            while (parentNavigablePath instanceof EntityIdentifierNavigablePath) {
                parentNavigablePath = parentNavigablePath.getParent();
                assert parentNavigablePath != null;
                parentModelPart = creationState.resolveModelPart(parentNavigablePath);
            }
        }
        while (parentModelPart instanceof EmbeddableValuedFetchable) {
            parentNavigablePath = parentNavigablePath.getParent();
            assert parentNavigablePath != null;
            parentModelPart = creationState.resolveModelPart(parentNavigablePath);
        }
        if (isBidirectionalAttributeName(parentNavigablePath, parentModelPart, fetchablePath, creationState)) {
            return createCircularBiDirectionalFetch(fetchablePath, fetchParent, parentNavigablePath, creationState);
        }
        /*
						class Child {
							@OneToOne
							private Mother mother;
						}

						class Mother {
							@OneToOne
							private Child stepMother;
						}

				We have a circularity but it is not bidirectional
			 */
        final TableGroup parentTableGroup = creationState.getSqlAstCreationState().getFromClauseAccess().getTableGroup(fetchParent.getNavigablePath());
        final DomainResult<?> foreignKeyDomainResult;
        assert !creationState.isResolvingCircularFetch();
        try {
            creationState.setResolvingCircularFetch(true);
            foreignKeyDomainResult = foreignKeyDescriptor.createDomainResult(fetchablePath, parentTableGroup, sideNature, creationState);
        } finally {
            creationState.setResolvingCircularFetch(false);
        }
        return new CircularFetchImpl(this, getEntityMappingType(), fetchTiming, fetchablePath, fetchParent, this, isSelectByUniqueKey(sideNature), fetchablePath, foreignKeyDomainResult);
    }
    return null;
}
Also used : AssociationKey(org.hibernate.metamodel.mapping.AssociationKey) TreatedNavigablePath(org.hibernate.query.spi.TreatedNavigablePath) NavigablePath(org.hibernate.query.spi.NavigablePath) EntityIdentifierNavigablePath(org.hibernate.query.sqm.spi.EntityIdentifierNavigablePath) CorrelatedTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedTableGroup) MappedByTableGroup(org.hibernate.sql.ast.tree.from.MappedByTableGroup) LazyTableGroup(org.hibernate.sql.ast.tree.from.LazyTableGroup) StandardTableGroup(org.hibernate.sql.ast.tree.from.StandardTableGroup) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) PluralTableGroup(org.hibernate.sql.ast.tree.from.PluralTableGroup) VirtualModelPart(org.hibernate.metamodel.mapping.VirtualModelPart) ModelPart(org.hibernate.metamodel.mapping.ModelPart) EmbeddableValuedModelPart(org.hibernate.metamodel.mapping.EmbeddableValuedModelPart) EntityIdentifierNavigablePath(org.hibernate.query.sqm.spi.EntityIdentifierNavigablePath) CircularFetchImpl(org.hibernate.sql.results.internal.domain.CircularFetchImpl) EmbeddableValuedFetchable(org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable)

Aggregations

AssociationKey (org.hibernate.metamodel.mapping.AssociationKey)1 EmbeddableValuedModelPart (org.hibernate.metamodel.mapping.EmbeddableValuedModelPart)1 ModelPart (org.hibernate.metamodel.mapping.ModelPart)1 VirtualModelPart (org.hibernate.metamodel.mapping.VirtualModelPart)1 NavigablePath (org.hibernate.query.spi.NavigablePath)1 TreatedNavigablePath (org.hibernate.query.spi.TreatedNavigablePath)1 EntityIdentifierNavigablePath (org.hibernate.query.sqm.spi.EntityIdentifierNavigablePath)1 CorrelatedTableGroup (org.hibernate.sql.ast.tree.from.CorrelatedTableGroup)1 LazyTableGroup (org.hibernate.sql.ast.tree.from.LazyTableGroup)1 MappedByTableGroup (org.hibernate.sql.ast.tree.from.MappedByTableGroup)1 PluralTableGroup (org.hibernate.sql.ast.tree.from.PluralTableGroup)1 StandardTableGroup (org.hibernate.sql.ast.tree.from.StandardTableGroup)1 TableGroup (org.hibernate.sql.ast.tree.from.TableGroup)1 EmbeddableValuedFetchable (org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable)1 CircularFetchImpl (org.hibernate.sql.results.internal.domain.CircularFetchImpl)1