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;
}
Aggregations