use of org.hibernate.sql.results.graph.DomainResult in project hibernate-orm by hibernate.
the class LoadPlanBuilderTest method testCascadeBasedBuild.
@Test
public void testCascadeBasedBuild(SessionFactoryScope scope) {
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
final EntityPersister entityDescriptor = (EntityPersister) sessionFactory.getRuntimeMetamodels().getEntityMappingType(Message.class);
final SingleIdEntityLoaderStandardImpl<?> loader = new SingleIdEntityLoaderStandardImpl<>(entityDescriptor, sessionFactory);
final LoadQueryInfluencers influencers = new LoadQueryInfluencers() {
@Override
public CascadingFetchProfile getEnabledCascadingFetchProfile() {
return CascadingFetchProfile.MERGE;
}
};
final SingleIdLoadPlan<?> loadPlan = loader.resolveLoadPlan(LockOptions.READ, influencers, sessionFactory);
final List<DomainResult<?>> domainResults = loadPlan.getJdbcSelect().getJdbcValuesMappingProducer().resolve(null, sessionFactory).getDomainResults();
assertThat(domainResults).hasSize(1);
final DomainResult<?> domainResult = domainResults.get(0);
assertThat(domainResult).isInstanceOf(EntityResult.class);
final EntityResult entityResult = (EntityResult) domainResult;
assertThat(entityResult.getFetches()).hasSize(2);
final Fetch txtFetch = entityResult.getFetches().get(0);
assertThat(txtFetch).isNotNull();
assertThat(txtFetch.getFetchedMapping().getFetchableName()).isEqualTo("msgTxt");
assertThat(txtFetch.getTiming()).isEqualTo(FetchTiming.IMMEDIATE);
final Fetch posterFetch = entityResult.getFetches().get(1);
assertThat(posterFetch).isNotNull();
assertThat(posterFetch.getFetchedMapping().getFetchableName()).isEqualTo("poster");
assertThat(posterFetch.getTiming()).isEqualTo(FetchTiming.IMMEDIATE);
}
use of org.hibernate.sql.results.graph.DomainResult in project hibernate-orm by hibernate.
the class ToOneAttributeMapping method generateFetch.
@Override
public EntityFetch generateFetch(FetchParent fetchParent, NavigablePath fetchablePath, FetchTiming fetchTiming, boolean selected, String resultVariable, DomainResultCreationState creationState) {
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
final FromClauseAccess fromClauseAccess = sqlAstCreationState.getFromClauseAccess();
final TableGroup parentTableGroup = fromClauseAccess.getTableGroup(fetchParent.getNavigablePath());
final NavigablePath parentNavigablePath = fetchablePath.getParent();
assert parentNavigablePath.equals(fetchParent.getNavigablePath()) || fetchParent.getNavigablePath() instanceof TreatedNavigablePath && parentNavigablePath.equals(fetchParent.getNavigablePath().getRealParent());
if (fetchTiming == FetchTiming.IMMEDIATE && selected) {
final TableGroup tableGroup;
if (fetchParent instanceof EntityResultJoinedSubclassImpl && ((EntityPersister) fetchParent.getReferencedModePart()).findDeclaredAttributeMapping(getPartName()) == null) {
final TableGroupJoin tableGroupJoin = createTableGroupJoin(fetchablePath, parentTableGroup, resultVariable, getJoinType(fetchablePath, parentTableGroup), true, false, creationState.getSqlAstCreationState());
parentTableGroup.addTableGroupJoin(tableGroupJoin);
tableGroup = tableGroupJoin.getJoinedGroup();
fromClauseAccess.registerTableGroup(fetchablePath, tableGroup);
} else {
tableGroup = fromClauseAccess.resolveTableGroup(fetchablePath, np -> {
final TableGroupJoin tableGroupJoin = createTableGroupJoin(fetchablePath, parentTableGroup, resultVariable, getDefaultSqlAstJoinType(parentTableGroup), true, false, creationState.getSqlAstCreationState());
parentTableGroup.addTableGroupJoin(tableGroupJoin);
return tableGroupJoin.getJoinedGroup();
});
}
final boolean added = creationState.registerVisitedAssociationKey(foreignKeyDescriptor.getAssociationKey());
AssociationKey additionalAssociationKey = null;
if (cardinality == Cardinality.LOGICAL_ONE_TO_ONE && bidirectionalAttributeName != null) {
final ModelPart bidirectionalModelPart = entityMappingType.findSubPart(bidirectionalAttributeName);
// Add the inverse association key side as well to be able to resolve to a CircularFetch
if (bidirectionalModelPart instanceof ToOneAttributeMapping) {
assert bidirectionalModelPart.getPartMappingType() == declaringTableGroupProducer;
final ToOneAttributeMapping bidirectionalAttribute = (ToOneAttributeMapping) bidirectionalModelPart;
final AssociationKey secondKey = bidirectionalAttribute.getForeignKeyDescriptor().getAssociationKey();
if (creationState.registerVisitedAssociationKey(secondKey)) {
additionalAssociationKey = secondKey;
}
}
}
final EntityFetchJoinedImpl entityFetchJoined = new EntityFetchJoinedImpl(fetchParent, this, tableGroup, fetchablePath, creationState);
if (added) {
creationState.removeVisitedAssociationKey(foreignKeyDescriptor.getAssociationKey());
}
if (additionalAssociationKey != null) {
creationState.removeVisitedAssociationKey(additionalAssociationKey);
}
return entityFetchJoined;
}
/*
1. No JoinTable
Model:
EntityA{
@ManyToOne
EntityB b
}
EntityB{
@ManyToOne
EntityA a
}
Relational:
ENTITY_A( id )
ENTITY_B( id, entity_a_id)
1.1 EntityA -> EntityB : as keyResult we need ENTITY_B.id
1.2 EntityB -> EntityA : as keyResult we need ENTITY_B.entity_a_id (FK referring column)
2. JoinTable
*/
final ForeignKeyDescriptor.Nature resolvingKeySideOfForeignKey = creationState.getCurrentlyResolvingForeignKeyPart();
final ForeignKeyDescriptor.Nature side;
if (resolvingKeySideOfForeignKey == ForeignKeyDescriptor.Nature.KEY && this.sideNature == ForeignKeyDescriptor.Nature.TARGET) {
// If we are currently resolving the key part of a foreign key we do not want to add joins.
// So if the lhs of this association is the target of the FK, we have to use the KEY part to avoid a join
side = ForeignKeyDescriptor.Nature.KEY;
} else {
side = this.sideNature;
}
final DomainResult<?> keyResult = foreignKeyDescriptor.createDomainResult(fetchablePath, parentTableGroup, side, creationState);
final boolean selectByUniqueKey = isSelectByUniqueKey(side);
if (fetchTiming == FetchTiming.IMMEDIATE) {
return new EntityFetchSelectImpl(fetchParent, this, fetchablePath, keyResult, selectByUniqueKey, creationState);
}
return new EntityDelayedFetchImpl(fetchParent, this, fetchablePath, keyResult, selectByUniqueKey);
}
use of org.hibernate.sql.results.graph.DomainResult in project hibernate-orm by hibernate.
the class CompoundNaturalIdMapping method createDomainResult.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ModelPart
@Override
public <T> DomainResult<T> createDomainResult(NavigablePath navigablePath, TableGroup tableGroup, String resultVariable, DomainResultCreationState creationState) {
assert navigablePath.getLocalName().equals(NaturalIdMapping.PART_NAME);
final SessionFactoryImplementor sessionFactory = creationState.getSqlAstCreationState().getCreationContext().getSessionFactory();
final JavaType<Object[]> jtd = sessionFactory.getTypeConfiguration().getJavaTypeRegistry().getDescriptor(Object[].class);
// register the table group under `...{natural-id}` as well
creationState.getSqlAstCreationState().getFromClauseAccess().resolveTableGroup(navigablePath, (np) -> tableGroup);
return (DomainResult<T>) new DomainResultImpl(navigablePath, this, jtd, resultVariable, creationState);
}
use of org.hibernate.sql.results.graph.DomainResult in project hibernate-orm by hibernate.
the class CollectionIdentifierDescriptorImpl method createDomainResult.
public DomainResult<?> createDomainResult(NavigablePath collectionPath, TableGroup tableGroup, DomainResultCreationState creationState) {
final SqlAstCreationState astCreationState = creationState.getSqlAstCreationState();
final SqlAstCreationContext astCreationContext = astCreationState.getCreationContext();
final SessionFactoryImplementor sessionFactory = astCreationContext.getSessionFactory();
final SqlExpressionResolver sqlExpressionResolver = astCreationState.getSqlExpressionResolver();
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(sqlExpressionResolver.resolveSqlExpression(SqlExpressionResolver.createColumnReferenceKey(tableGroup.getPrimaryTableReference(), columnName), p -> new ColumnReference(tableGroup.getPrimaryTableReference().getIdentificationVariable(), columnName, false, null, null, type, sessionFactory)), type.getJavaTypeDescriptor(), sessionFactory.getTypeConfiguration());
// noinspection unchecked
return new BasicResult<>(sqlSelection.getValuesArrayPosition(), null, (JavaType<Object>) type.getJavaTypeDescriptor(), collectionPath);
}
use of org.hibernate.sql.results.graph.DomainResult in project hibernate-orm by hibernate.
the class LoaderSelectBuilder method generateSelect.
private SelectStatement generateSelect() {
if (loadable instanceof PluralAttributeMapping) {
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) loadable;
if (pluralAttributeMapping.getMappedType().getCollectionSemantics() instanceof BagSemantics) {
currentBagRole = pluralAttributeMapping.getNavigableRole().getNavigableName();
}
}
final NavigablePath rootNavigablePath = new NavigablePath(loadable.getRootPathName());
final QuerySpec rootQuerySpec = new QuerySpec(true);
final List<DomainResult<?>> domainResults;
final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState(rootQuerySpec, new SqlAliasBaseManager(), new SimpleFromClauseAccessImpl(), lockOptions, this::visitFetches, forceIdentifierSelection, creationContext);
final TableGroup rootTableGroup = loadable.createRootTableGroup(true, rootNavigablePath, null, () -> rootQuerySpec::applyPredicate, sqlAstCreationState, creationContext);
rootQuerySpec.getFromClause().addRoot(rootTableGroup);
sqlAstCreationState.getFromClauseAccess().registerTableGroup(rootNavigablePath, rootTableGroup);
registerPluralTableGroupParts(sqlAstCreationState.getFromClauseAccess(), rootTableGroup);
if (partsToSelect != null && !partsToSelect.isEmpty()) {
domainResults = new ArrayList<>(partsToSelect.size());
for (ModelPart part : partsToSelect) {
final NavigablePath navigablePath = rootNavigablePath.append(part.getPartName());
final TableGroup tableGroup;
if (part instanceof TableGroupJoinProducer) {
final TableGroupJoinProducer tableGroupJoinProducer = (TableGroupJoinProducer) part;
final TableGroupJoin tableGroupJoin = tableGroupJoinProducer.createTableGroupJoin(navigablePath, rootTableGroup, null, SqlAstJoinType.LEFT, true, false, sqlAstCreationState);
rootTableGroup.addTableGroupJoin(tableGroupJoin);
tableGroup = tableGroupJoin.getJoinedGroup();
sqlAstCreationState.getFromClauseAccess().registerTableGroup(navigablePath, tableGroup);
registerPluralTableGroupParts(sqlAstCreationState.getFromClauseAccess(), tableGroup);
} else {
tableGroup = rootTableGroup;
}
domainResults.add(part.createDomainResult(navigablePath, tableGroup, null, sqlAstCreationState));
}
} else {
// use the one passed to the constructor or create one (maybe always create and pass?)
// allows re-use as they can be re-used to save on memory - they
// do not share state between
// noinspection rawtypes
final DomainResult domainResult;
if (this.cachedDomainResult != null) {
// used the one passed to the constructor
domainResult = this.cachedDomainResult;
} else {
// create one
domainResult = loadable.createDomainResult(rootNavigablePath, rootTableGroup, null, sqlAstCreationState);
}
// noinspection unchecked
domainResults = Collections.singletonList(domainResult);
}
for (ModelPart restrictedPart : restrictedParts) {
final int numberOfRestrictionColumns = restrictedPart.getJdbcTypeCount();
applyRestriction(rootQuerySpec, rootNavigablePath, rootTableGroup, restrictedPart, numberOfRestrictionColumns, jdbcParameterConsumer, sqlAstCreationState);
}
if (loadable instanceof PluralAttributeMapping) {
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) loadable;
applyFiltering(rootQuerySpec, rootTableGroup, pluralAttributeMapping, sqlAstCreationState);
applyOrdering(rootTableGroup, pluralAttributeMapping);
} else {
applyFiltering(rootQuerySpec, rootTableGroup, (Restrictable) loadable, sqlAstCreationState);
}
if (orderByFragments != null) {
orderByFragments.forEach(entry -> entry.getKey().apply(rootQuerySpec, entry.getValue(), sqlAstCreationState));
}
return new SelectStatement(rootQuerySpec, domainResults);
}
Aggregations