use of org.hibernate.metamodel.mapping.EntityMappingType in project hibernate-orm by hibernate.
the class NonRootTablePolymorphicTests method verifyRuntimeModel.
@Test
public void verifyRuntimeModel(SessionFactoryScope scope) {
final EntityMappingType rootEntity = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType(Root.class);
final EntityMappingType subEntity = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType(Sub.class);
final EntityMappingType leafEntity = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType(Leaf.class);
final EntityMappingType childEntity = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType(SubChild.class);
final EntityMappingType parentEntity = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType(SubParent.class);
// check Sub#child fk
final ToOneAttributeMapping childAttribute = (ToOneAttributeMapping) subEntity.findAttributeMapping("child");
final SimpleForeignKeyDescriptor childFk = (SimpleForeignKeyDescriptor) childAttribute.getForeignKeyDescriptor();
assertThat(childFk.getKeyTable(), is("sub"));
assertThat(childFk.getTargetTable(), is("sub_child"));
assertThat(childFk.getJdbcTypeCount(), is(1));
assertThat(childFk.getKeyPart().getSelectionExpression(), is("child_fk"));
assertThat(childFk.getTargetPart().getSelectionExpression(), is("child_id"));
// check Parent#sub fk
final ToOneAttributeMapping subAttribute = (ToOneAttributeMapping) parentEntity.findAttributeMapping("sub");
final SimpleForeignKeyDescriptor subFk = (SimpleForeignKeyDescriptor) subAttribute.getForeignKeyDescriptor();
assertThat(subFk.getKeyTable(), is("sub_parent"));
assertThat(subFk.getTargetTable(), is("sub"));
assertThat(subFk.getJdbcTypeCount(), is(1));
assertThat(subFk.getKeyPart().getSelectionExpression(), is("parent_sub_fk"));
assertThat(subFk.getTargetPart().getSelectionExpression(), is("sub_id"));
scope.inTransaction((session) -> {
session.createQuery("from SubParent p join fetch p.sub").list();
session.createQuery("from SubGroup p join fetch p.manyToManySubs").list();
session.createQuery("from SubGroup p join fetch p.oneToManySubs").list();
});
// for sure the inheritance keys are messed up in the mapping model
}
use of org.hibernate.metamodel.mapping.EntityMappingType in project hibernate-orm by hibernate.
the class AbstractCompositeIdAndNaturalIdTest method testNaturalIdNullability.
@Test
@TestForIssue(jiraKey = "HHH-10360")
public void testNaturalIdNullability(SessionFactoryScope scope) {
final EntityMappingType accountMapping = scope.getSessionFactory().getRuntimeMetamodels().getEntityMappingType(Account.class);
final SingularAttributeMapping shortCodeMapping = ((SimpleNaturalIdMapping) accountMapping.getNaturalIdMapping()).getAttribute();
final StateArrayContributorMetadata shortCodeMetadata = shortCodeMapping.getAttributeMetadataAccess().resolveAttributeMetadata(null);
assertThat(shortCodeMetadata.isNullable(), is(false));
final EntityPersister rootEntityPersister = accountMapping.getRootEntityDescriptor().getEntityPersister();
final int shortCodeLegacyPropertyIndex = rootEntityPersister.getEntityMetamodel().getPropertyIndex("shortCode");
assertThat(shortCodeLegacyPropertyIndex, is(0));
assertThat(rootEntityPersister.getPropertyNullability()[shortCodeLegacyPropertyIndex], is(false));
}
use of org.hibernate.metamodel.mapping.EntityMappingType in project hibernate-orm by hibernate.
the class MutableNaturalIdTest method testNaturalIdNullability.
@Test
@TestForIssue(jiraKey = "HHH-10360")
public void testNaturalIdNullability(SessionFactoryScope scope) {
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
final EntityMappingType entityMappingType = sessionFactory.getRuntimeMetamodels().getEntityMappingType(User.class);
final EntityPersister persister = entityMappingType.getEntityPersister();
final EntityMetamodel entityMetamodel = persister.getEntityMetamodel();
// nullability is not specified, so it should be non-nullable by hbm-specific default
assertFalse(persister.getPropertyNullability()[entityMetamodel.getPropertyIndex("name")]);
assertFalse(persister.getPropertyNullability()[entityMetamodel.getPropertyIndex("org")]);
}
use of org.hibernate.metamodel.mapping.EntityMappingType in project hibernate-orm by hibernate.
the class ImmutableManyToOneNaturalIdAnnotationTest method testNaturalIdNullability.
@Test
@TestForIssue(jiraKey = "HHH-10360")
public void testNaturalIdNullability(SessionFactoryScope scope) {
// nullability is not specified for either properties making up
// the natural ID, so they should be nullable by annotation-specific default
final RuntimeMetamodels runtimeMetamodels = scope.getSessionFactory().getRuntimeMetamodels();
final EntityMappingType childMapping = runtimeMetamodels.getEntityMappingType(Child.class.getName());
final EntityPersister persister = childMapping.getEntityPersister();
final EntityMetamodel entityMetamodel = persister.getEntityMetamodel();
final int nameIndex = entityMetamodel.getPropertyIndex("name");
final int parentIndex = entityMetamodel.getPropertyIndex("parent");
// checking alphabetic sort in relation to EntityPersister/EntityMetamodel
assertThat(nameIndex, lessThan(parentIndex));
assertFalse(persister.getPropertyUpdateability()[nameIndex]);
assertFalse(persister.getPropertyUpdateability()[parentIndex]);
assertTrue(persister.getPropertyNullability()[nameIndex]);
assertTrue(persister.getPropertyNullability()[parentIndex]);
final NaturalIdMapping naturalIdMapping = childMapping.getNaturalIdMapping();
assertNotNull(naturalIdMapping);
assertThat(naturalIdMapping.getNaturalIdAttributes().size(), is(2));
// access by list-index should again be alphabetically sorted
final SingularAttributeMapping first = naturalIdMapping.getNaturalIdAttributes().get(0);
assertThat(first.getAttributeName(), is("name"));
final StateArrayContributorMetadata firstMetadata = first.getAttributeMetadataAccess().resolveAttributeMetadata(null);
assertFalse(firstMetadata.getMutabilityPlan().isMutable());
final SingularAttributeMapping second = naturalIdMapping.getNaturalIdAttributes().get(1);
assertThat(second.getAttributeName(), is("parent"));
final StateArrayContributorMetadata secondMetadata = second.getAttributeMetadataAccess().resolveAttributeMetadata(null);
assertFalse(secondMetadata.getMutabilityPlan().isMutable());
}
use of org.hibernate.metamodel.mapping.EntityMappingType in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitTableGroup.
private Expression visitTableGroup(TableGroup tableGroup, SqmFrom<?, ?> path) {
final ModelPartContainer modelPart;
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
// For plain SqmFrom node uses, prefer the mapping type from the context if possible
if (!(inferredValueMapping instanceof ModelPartContainer)) {
modelPart = tableGroup.getModelPart();
} else {
modelPart = (ModelPartContainer) inferredValueMapping;
}
final ModelPart resultModelPart;
final ModelPart interpretationModelPart;
final TableGroup parentGroupToUse;
if (modelPart instanceof ToOneAttributeMapping) {
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) modelPart;
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(toOneAttributeMapping.getSideNature().inverse());
if (tableGroup.getModelPart().getPartMappingType() == modelPart.getPartMappingType()) {
resultModelPart = targetPart;
} else {
// If the table group is for a different mapping type i.e. an inheritance subtype,
// lookup the target part on that mapping type
resultModelPart = tableGroup.getModelPart().findSubPart(targetPart.getPartName(), null);
}
interpretationModelPart = modelPart;
parentGroupToUse = null;
} else if (modelPart instanceof PluralAttributeMapping) {
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) modelPart;
final CollectionPart elementDescriptor = pluralAttributeMapping.getElementDescriptor();
if (elementDescriptor instanceof EntityCollectionPart) {
// Usually, we need to resolve to the PK for visitTableGroup
final EntityCollectionPart collectionPart = (EntityCollectionPart) elementDescriptor;
final ModelPart collectionTargetPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature().inverse());
final EntityIdentifierMapping identifierMapping = collectionPart.getEntityMappingType().getIdentifierMapping();
// If the FK points to the PK, we can use the FK part though, if this is not a root
if (collectionTargetPart == identifierMapping && !(path instanceof SqmRoot<?>)) {
resultModelPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature());
} else {
resultModelPart = identifierMapping;
}
} else {
resultModelPart = elementDescriptor;
}
interpretationModelPart = elementDescriptor;
parentGroupToUse = null;
} else if (modelPart instanceof EntityCollectionPart) {
// Usually, we need to resolve to the PK for visitTableGroup
final EntityCollectionPart collectionPart = (EntityCollectionPart) modelPart;
final ModelPart collectionTargetPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature().inverse());
final EntityIdentifierMapping identifierMapping = collectionPart.getEntityMappingType().getIdentifierMapping();
// If the FK points to the PK, we can use the FK part though, if this is not a root
if (collectionTargetPart == identifierMapping && !(path instanceof SqmRoot<?>)) {
resultModelPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature());
} else {
resultModelPart = identifierMapping;
}
interpretationModelPart = modelPart;
parentGroupToUse = findTableGroup(tableGroup.getNavigablePath().getParent());
} else if (modelPart instanceof EntityMappingType) {
resultModelPart = ((EntityMappingType) modelPart).getIdentifierMapping();
interpretationModelPart = modelPart;
// todo: I think this will always be null anyways because EntityMappingType will only be the model part
// of a TableGroup if that is a root TableGroup, so check if we can just switch to null
parentGroupToUse = findTableGroup(tableGroup.getNavigablePath().getParent());
} else {
resultModelPart = modelPart;
interpretationModelPart = modelPart;
parentGroupToUse = null;
}
final NavigablePath navigablePath;
if (interpretationModelPart == modelPart) {
navigablePath = tableGroup.getNavigablePath();
} else {
navigablePath = tableGroup.getNavigablePath().append(interpretationModelPart.getPartName());
}
final Expression result;
if (interpretationModelPart instanceof EntityValuedModelPart) {
final boolean expandToAllColumns;
if (currentClauseStack.getCurrent() == Clause.GROUP) {
// When the table group is known to be fetched i.e. a fetch join
// but also when the from clause is part of the select clause
// we need to expand to all columns, as we also expand this to all columns in the select clause
expandToAllColumns = tableGroup.isFetched() || selectClauseContains(path);
} else {
expandToAllColumns = false;
}
final EntityValuedModelPart mapping = (EntityValuedModelPart) interpretationModelPart;
EntityMappingType mappingType;
if (path instanceof SqmTreatedPath) {
mappingType = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel().findEntityDescriptor(((SqmTreatedPath<?, ?>) path).getTreatTarget().getHibernateEntityName());
} else {
mappingType = mapping.getEntityMappingType();
}
result = EntityValuedPathInterpretation.from(navigablePath, parentGroupToUse == null ? tableGroup : parentGroupToUse, expandToAllColumns ? null : resultModelPart, (EntityValuedModelPart) interpretationModelPart, mappingType, this);
} else if (interpretationModelPart instanceof EmbeddableValuedModelPart) {
final EmbeddableValuedModelPart mapping = (EmbeddableValuedModelPart) resultModelPart;
result = new EmbeddableValuedPathInterpretation<>(mapping.toSqlExpression(tableGroup, currentClauseStack.getCurrent(), this, getSqlAstCreationState()), navigablePath, (EmbeddableValuedModelPart) interpretationModelPart, tableGroup);
} else {
assert interpretationModelPart instanceof BasicValuedModelPart;
final BasicValuedModelPart mapping = (BasicValuedModelPart) resultModelPart;
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath.append(resultModelPart.getPartName()), mapping.getContainingTableExpression());
final Expression expression = getSqlExpressionResolver().resolveSqlExpression(SqlExpressionResolver.createColumnReferenceKey(tableReference, mapping.getSelectionExpression()), sacs -> new ColumnReference(tableReference.getIdentificationVariable(), mapping, getCreationContext().getSessionFactory()));
final ColumnReference columnReference;
if (expression instanceof ColumnReference) {
columnReference = (ColumnReference) expression;
} else if (expression instanceof SqlSelectionExpression) {
final Expression selectedExpression = ((SqlSelectionExpression) expression).getSelection().getExpression();
assert selectedExpression instanceof ColumnReference;
columnReference = (ColumnReference) selectedExpression;
} else {
throw new UnsupportedOperationException("Unsupported basic-valued path expression : " + expression);
}
result = new BasicValuedPathInterpretation<>(columnReference, navigablePath, (BasicValuedModelPart) interpretationModelPart, tableGroup);
}
return withTreatRestriction(result, path);
}
Aggregations