HHH-18683 Change metamodel implementations to comply with JPA spec

This commit is contained in:
Marco Belladelli 2024-10-09 11:10:00 +02:00 committed by Steve Ebersole
parent a4233cf34d
commit 8dca8637a8
7 changed files with 134 additions and 36 deletions

View File

@ -78,16 +78,40 @@ public interface JpaMetamodel extends Metamodel {
<X> EntityDomainType<X> resolveHqlEntityReference(String entityName);
/**
* Same as {@link #managedType} except {@code null} is returned rather
* Same as {@link #managedType(Class)} except {@code null} is returned rather
* than throwing an exception
*/
<X> ManagedDomainType<X> findManagedType(Class<X> cls);
@Nullable <X> ManagedDomainType<X> findManagedType(Class<X> cls);
/**
* Same as {@link #entity} except {@code null} is returned rather
* Same as {@link #entity(Class)} except {@code null} is returned rather
* than throwing an exception
*/
<X> EntityDomainType<X> findEntityType(Class<X> cls);
@Nullable <X> EntityDomainType<X> findEntityType(Class<X> cls);
/**
* Same as {@link #embeddable(Class)} except {@code null} is returned rather
* than throwing an exception
*/
@Nullable <X> EmbeddableDomainType<X> findEmbeddableType(Class<X> cls);
/**
* Same as {@link #managedType(String)} except {@code null} is returned rather
* than throwing an exception
*/
@Nullable <X> ManagedDomainType<X> findManagedType(@Nullable String typeName);
/**
* Same as {@link #entity(String)} except {@code null} is returned rather
* than throwing an exception
*/
@Nullable EntityDomainType<?> findEntityType(@Nullable String entityName);
/**
* Same as {@link #embeddable(String)} except {@code null} is returned rather
* than throwing an exception
*/
@Nullable EmbeddableDomainType<?> findEmbeddableType(@Nullable String embeddableName);
String qualifyImportableName(String queryName);

View File

@ -134,33 +134,61 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
}
@Override
public <X> ManagedDomainType<X> managedType(String typeName) {
public @Nullable <X> ManagedDomainType<X> findManagedType(@Nullable String typeName) {
//noinspection unchecked
return typeName == null ? null : (ManagedDomainType<X>) managedTypeByName.get( typeName );
}
@Override
public EntityDomainType<?> entity(String entityName) {
public <X> ManagedDomainType<X> managedType(String typeName) {
final ManagedDomainType<X> managedType = findManagedType( typeName );
if ( managedType == null ) {
throw new IllegalArgumentException("Not a managed type: " + typeName);
}
return managedType;
}
@Override
@Nullable public EntityDomainType<?> findEntityType(@Nullable String entityName) {
if ( entityName == null ) {
return null;
}
final ManagedDomainType<?> managedType = managedTypeByName.get( entityName );
if ( !( managedType instanceof EntityDomainType<?> ) ) {
if ( !( managedType instanceof EntityDomainType<?> entityDomainType ) ) {
return null;
}
return (EntityDomainType<?>) managedType;
return entityDomainType;
}
@Override
public EmbeddableDomainType<?> embeddable(String embeddableName) {
public EntityDomainType<?> entity(String entityName) {
final EntityDomainType<?> entityType = findEntityType( entityName );
if ( entityType == null ) {
// per JPA
throw new IllegalArgumentException("Not an entity: " + entityName);
}
return entityType;
}
@Override
@Nullable public EmbeddableDomainType<?> findEmbeddableType(@Nullable String embeddableName) {
if ( embeddableName == null ) {
return null;
}
final ManagedDomainType<?> managedType = managedTypeByName.get( embeddableName );
if ( !( managedType instanceof EmbeddableDomainType<?> ) ) {
if ( !( managedType instanceof EmbeddableDomainType<?> embeddableDomainType) ) {
return null;
}
return (EmbeddableDomainType<?>) managedType;
return embeddableDomainType;
}
@Override
public EmbeddableDomainType<?> embeddable(String embeddableName) {
final EmbeddableDomainType<?> embeddableType = findEmbeddableType( embeddableName );
if ( embeddableType == null ) {
throw new IllegalArgumentException("Not an embeddable: " + embeddableName);
}
return embeddableType;
}
@Override
@ -172,7 +200,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
entityName = importInfo.importedName;
}
final EntityDomainType<?> entityDescriptor = entity( entityName );
final EntityDomainType<?> entityDescriptor = findEntityType( entityName );
if ( entityDescriptor != null ) {
//noinspection unchecked
return (EntityDomainType<X>) entityDescriptor;
@ -201,13 +229,23 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
}
@Override
public <X> ManagedDomainType<X> findManagedType(Class<X> cls) {
@Nullable public <X> ManagedDomainType<X> findManagedType(Class<X> cls) {
//noinspection unchecked
return (ManagedDomainType<X>) managedTypeByClass.get( cls );
}
@Override
public <X> EntityDomainType<X> findEntityType(Class<X> cls) {
public <X> ManagedDomainType<X> managedType(Class<X> cls) {
final ManagedDomainType<X> type = findManagedType( cls );
if ( type == null ) {
// per JPA
throw new IllegalArgumentException( "Not a managed type: " + cls );
}
return type;
}
@Override
@Nullable public <X> EntityDomainType<X> findEntityType(Class<X> cls) {
final ManagedType<?> type = managedTypeByClass.get( cls );
if ( !( type instanceof EntityDomainType<?> ) ) {
return null;
@ -217,35 +255,31 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
}
@Override
public <X> ManagedDomainType<X> managedType(Class<X> cls) {
final ManagedType<?> type = managedTypeByClass.get( cls );
if ( type == null ) {
// per JPA
throw new IllegalArgumentException( "Not a managed type: " + cls );
public <X> EntityDomainType<X> entity(Class<X> cls) {
final EntityDomainType<X> entityType = findEntityType( cls );
if ( entityType == null ) {
throw new IllegalArgumentException( "Not an entity: " + cls.getName() );
}
//noinspection unchecked
return (ManagedDomainType<X>) type;
return entityType;
}
@Override
public <X> EntityDomainType<X> entity(Class<X> cls) {
public @Nullable <X> EmbeddableDomainType<X> findEmbeddableType(Class<X> cls) {
final ManagedType<?> type = managedTypeByClass.get( cls );
if ( !( type instanceof EntityDomainType<?> ) ) {
throw new IllegalArgumentException( "Not an entity: " + cls.getName() );
if ( !( type instanceof EmbeddableDomainType<?> ) ) {
return null;
}
//noinspection unchecked
return (EntityDomainType<X>) type;
return (EmbeddableDomainType<X>) type;
}
@Override
public <X> EmbeddableDomainType<X> embeddable(Class<X> cls) {
final ManagedType<?> type = managedTypeByClass.get( cls );
if ( !( type instanceof EmbeddableDomainType<?> ) ) {
final EmbeddableDomainType<X> embeddableType = findEmbeddableType( cls );
if ( embeddableType == null ) {
throw new IllegalArgumentException( "Not an embeddable: " + cls.getName() );
}
//noinspection unchecked
return (EmbeddableDomainType<X>) type;
return embeddableType;
}
private Collection<ManagedDomainType<?>> getAllManagedTypes() {
@ -441,7 +475,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
definition.getEntityName(),
definition.getJpaEntityName()
);
final EntityDomainType<?> entityType = entity( definition.getEntityName() );
final EntityDomainType<?> entityType = findEntityType( definition.getEntityName() );
if ( entityType == null ) {
throw new IllegalArgumentException(
"Attempted to register named entity graph [" + definition.getRegisteredName()

View File

@ -17,6 +17,7 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.EntityNameResolver;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
@ -459,16 +460,31 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
return jpaMetamodel.getEmbeddables();
}
@Override
public @Nullable <X> ManagedDomainType<X> findManagedType(@Nullable String typeName) {
return jpaMetamodel.findManagedType( typeName );
}
@Override
public <X> ManagedDomainType<X> managedType(String typeName) {
return jpaMetamodel.managedType( typeName );
}
@Override
public @Nullable EntityDomainType<?> findEntityType(@Nullable String entityName) {
return jpaMetamodel.findEntityType( entityName );
}
@Override
public EntityDomainType<?> entity(String entityName) {
return jpaMetamodel.entity( entityName );
}
@Override
public @Nullable EmbeddableDomainType<?> findEmbeddableType(@Nullable String embeddableName) {
return jpaMetamodel.findEmbeddableType( embeddableName );
}
@Override
public EmbeddableDomainType<?> embeddable(String embeddableName) {
return jpaMetamodel.embeddable( embeddableName );
@ -494,6 +510,11 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
return jpaMetamodel.findEntityType( cls );
}
@Override
public @Nullable <X> EmbeddableDomainType<X> findEmbeddableType(Class<X> cls) {
return jpaMetamodel.findEmbeddableType( cls );
}
@Override
public String qualifyImportableName(String queryName) {
return jpaMetamodel.qualifyImportableName( queryName );

View File

@ -71,7 +71,7 @@ public class FullyQualifiedReflectivePathTerminal<E>
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// See if it is an entity-type literal
final EntityDomainType<?> entityDescriptor = creationContext.getJpaMetamodel().entity( fullPath );
final EntityDomainType<?> entityDescriptor = creationContext.getJpaMetamodel().findEntityType( fullPath );
if ( entityDescriptor != null ) {
return new SqmLiteralEntityType<>( entityDescriptor, creationContext.getNodeBuilder() );
}

View File

@ -1242,11 +1242,12 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
private EntityDomainType<R> getResultEntity() {
final JpaMetamodel jpaMetamodel = creationContext.getJpaMetamodel();
if ( expectedResultEntity != null ) {
final EntityDomainType<?> entityDescriptor = jpaMetamodel.entity( expectedResultEntity );
final EntityDomainType<?> entityDescriptor = jpaMetamodel.findEntityType( expectedResultEntity );
if ( entityDescriptor == null ) {
throw new SemanticException( "Query has no 'from' clause, and the result type '"
+ expectedResultEntity + "' is not an entity type", query );
}
//noinspection unchecked
return (EntityDomainType<R>) entityDescriptor;
}
else if ( expectedResultType != null ) {

View File

@ -3114,9 +3114,8 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
if ( tableGroup.getModelPart() instanceof EmbeddableValuedModelPart ) {
persister = null;
final EmbeddableDomainType<?> embeddableDomainType = creationContext.getSessionFactory()
.getRuntimeMetamodels()
.getJpaMetamodel()
.embeddable( treatTargetTypeName );
.findEmbeddableType( treatTargetTypeName );
if ( embeddableDomainType == null || !embeddableDomainType.isPolymorphic() ) {
return;
}

View File

@ -779,6 +779,16 @@ public abstract class MockSessionFactory
: null;
}
@Override
public @Nullable EntityDomainType<?> findEntityType(@Nullable String entityName) {
if ( isEntityDefined(entityName) ) {
return new MockEntityDomainType<>(entityName);
}
else {
return null;
}
}
@Override
public String qualifyImportableName(String queryName) {
if (isClassDefined(queryName)) {
@ -794,9 +804,18 @@ public abstract class MockSessionFactory
@Override
public <X> ManagedDomainType<X> managedType(String typeName) {
final ManagedDomainType<X> managedType = findManagedType( typeName );
if ( managedType == null ) {
throw new IllegalArgumentException("Not a managed type: " + typeName);
}
return managedType;
}
@Override
public @Nullable <X> ManagedDomainType<X> findManagedType(@Nullable String typeName) {
final String entityName = qualifyName( typeName );
//noinspection unchecked
return entityName == null ? null : (ManagedDomainType<X>) entity( entityName );
return entityName == null ? null : (ManagedDomainType<X>) findEntityType( entityName );
}
@Override