cleanup more generic typing issues around paths and graphs

simplify the whole appliesTo() thing which was convoluted and overly-complex
This commit is contained in:
Gavin King 2023-07-03 13:26:11 +02:00
parent 6299ceb61d
commit 617ce3206e
49 changed files with 311 additions and 472 deletions

View File

@ -24,10 +24,6 @@ import org.hibernate.metamodel.model.domain.PersistentAttribute;
*/
public interface RootGraph<J> extends Graph<J>, EntityGraph<J> {
// boolean appliesTo(String entityName);
//
// boolean appliesTo(Class<?> entityType);
@Override
RootGraph<J> makeRootGraph(String name, boolean mutable);

View File

@ -7,22 +7,18 @@
package org.hibernate.graph.internal;
import org.hibernate.graph.SubGraph;
import org.hibernate.graph.spi.GraphHelper;
import org.hibernate.graph.spi.GraphImplementor;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import jakarta.persistence.EntityGraph;
/**
* The Hibernate implementation of the JPA EntityGraph contract.
* Implementation of the JPA-defined {@link jakarta.persistence.EntityGraph} interface.
*
* @author Steve Ebersole
*/
public class RootGraphImpl<J> extends AbstractGraph<J> implements EntityGraph<J>, RootGraphImplementor<J> {
public class RootGraphImpl<J> extends AbstractGraph<J> implements RootGraphImplementor<J> {
private final String name;
@ -66,30 +62,7 @@ public class RootGraphImpl<J> extends AbstractGraph<J> implements EntityGraph<J>
}
@Override
public boolean appliesTo(EntityDomainType<?> entityType, JpaMetamodel metamodel) {
final ManagedDomainType<J> managedTypeDescriptor = getGraphedType();
if ( managedTypeDescriptor.equals( entityType ) ) {
return true;
}
IdentifiableDomainType<?> superType = entityType.getSupertype();
while ( superType != null ) {
if ( managedTypeDescriptor.equals( superType ) ) {
return true;
}
superType = superType.getSupertype();
}
return false;
}
@Override
public boolean appliesTo(String entityName, JpaMetamodel metamodel) {
return appliesTo( metamodel.entity( entityName ), metamodel );
}
@Override
public boolean appliesTo(Class<?> type, JpaMetamodel metamodel) {
return appliesTo( metamodel.entity( type ), metamodel );
public boolean appliesTo(EntityDomainType<?> entityType) {
return GraphHelper.appliesTo( this, entityType );
}
}

View File

@ -7,10 +7,11 @@
package org.hibernate.graph.internal;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
/**
* Implementation of the JPA-defined {@link jakarta.persistence.Subgraph} interface.
*
* @author Steve Ebersole
*/
public class SubGraphImpl<J> extends AbstractGraph<J> implements SubGraphImplementor<J> {
@ -38,25 +39,4 @@ public class SubGraphImpl<J> extends AbstractGraph<J> implements SubGraphImpleme
return super.addKeySubGraph( attributeName );
}
@Override
public boolean appliesTo(ManagedDomainType<?> managedType, JpaMetamodel metamodel) {
if ( getGraphedType().equals( managedType ) ) {
return true;
}
ManagedDomainType<?> superType = managedType.getSuperType();
while ( superType != null ) {
if ( superType.equals( managedType ) ) {
return true;
}
superType = superType.getSuperType();
}
return false;
}
@Override
public boolean appliesTo(Class<?> javaType, JpaMetamodel metamodel) {
return appliesTo( metamodel.managedType( javaType ), metamodel );
}
}

View File

@ -33,13 +33,13 @@ public interface AttributeNodeImplementor<J> extends AttributeNode<J>, GraphNode
}
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
default Map<Class<? extends J>, SubGraph<? extends J>> getSubGraphs() {
return (Map) getSubGraphMap();
}
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
default Map<Class<? extends J>, SubGraph<? extends J>> getKeySubGraphs() {
return (Map) getKeySubGraphMap();
}
@ -51,7 +51,7 @@ public interface AttributeNodeImplementor<J> extends AttributeNode<J>, GraphNode
}
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
default Map<Class, Subgraph> getKeySubgraphs() {
return (Map) getKeySubGraphMap();
}

View File

@ -6,11 +6,8 @@
*/
package org.hibernate.graph.spi;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.graph.Graph;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
/**
* Helper containing utilities useful for graph handling
@ -18,41 +15,17 @@ import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
* @author Steve Ebersole
*/
public class GraphHelper {
@SuppressWarnings("unchecked")
public static <J> SimpleDomainType<J> resolveKeyTypeDescriptor(SingularPersistentAttribute attribute) {
// only valid for entity-valued attributes where the entity has a
// composite id
final SimpleDomainType attributeType = attribute.getType();
if ( attributeType instanceof IdentifiableDomainType ) {
return ( (IdentifiableDomainType) attributeType ).getIdType();
}
return null;
public static boolean appliesTo(Graph<?> graph, ManagedDomainType<?> managedType) {
final ManagedDomainType<?> graphedType = graph.getGraphedType();
ManagedDomainType<?> superType = managedType;
while ( superType != null ) {
if ( graphedType.equals( superType ) ) {
return true;
}
superType = superType.getSuperType();
}
return false;
}
@SuppressWarnings({"unchecked", "ConstantConditions"})
public static <J> SimpleDomainType<J> resolveKeyTypeDescriptor(PluralPersistentAttribute attribute) {
if ( attribute instanceof SingularPersistentAttribute ) {
// only valid for entity-valued attributes where the entity has a
// composite id
final SimpleDomainType attributeType = ( (SingularPersistentAttribute) attribute ).getType();
if ( attributeType instanceof IdentifiableDomainType ) {
return ( (IdentifiableDomainType) attributeType ).getIdType();
}
return null;
}
else if ( attribute instanceof PluralPersistentAttribute ) {
if ( attribute instanceof MapPersistentAttribute ) {
return ( (MapPersistentAttribute) attribute ).getKeyType();
}
return null;
}
throw new IllegalArgumentException(
"Unexpected Attribute Class [" + attribute.getClass().getName()
+ "] - expecting SingularAttributeImplementor or PluralAttributeImplementor"
);
}
}

View File

@ -13,8 +13,6 @@ import org.hibernate.graph.AttributeNode;
import org.hibernate.graph.CannotBecomeEntityGraphException;
import org.hibernate.graph.CannotContainSubGraphException;
import org.hibernate.graph.Graph;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
@ -26,15 +24,11 @@ import org.hibernate.metamodel.model.domain.PersistentAttribute;
*/
public interface GraphImplementor<J> extends Graph<J>, GraphNodeImplementor<J> {
boolean appliesTo(ManagedDomainType<?> managedType, JpaMetamodel metamodel);
boolean appliesTo(Class<?> javaType, JpaMetamodel metamodel);
void merge(GraphImplementor<? extends J> other);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Co-variant returns
// Covariant returns
@Override
RootGraphImplementor<J> makeRootGraph(String name, boolean mutable)

View File

@ -8,25 +8,17 @@ package org.hibernate.graph.spi;
import org.hibernate.graph.RootGraph;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
/**
* Integration version of the {@link RootGraph} contract
* Integration version of the {@link RootGraph} contract.
*
* @author Steve Ebersole
*
* @see SubGraphImplementor
*/
public interface RootGraphImplementor<J> extends RootGraph<J>, GraphImplementor<J> {
boolean appliesTo(String entityName, JpaMetamodel metamodel);
boolean appliesTo(EntityDomainType<?> entityType, JpaMetamodel metamodel);
@Override
default boolean appliesTo(ManagedDomainType<?> managedType, JpaMetamodel metamodel) {
assert managedType instanceof EntityDomainType;
return appliesTo( (EntityDomainType<?>) managedType, metamodel );
}
boolean appliesTo(EntityDomainType<?> entityType);
@Override
RootGraphImplementor<J> makeRootGraph(String name, boolean mutable);

View File

@ -12,11 +12,14 @@ import org.hibernate.graph.SubGraph;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
/**
* Integration version of the {@link SubGraph} contract
* Integration version of the {@link SubGraph} contract.
*
* @author Steve Ebersole
*
* @see RootGraphImplementor
*/
public interface SubGraphImplementor<J> extends SubGraph<J>, GraphImplementor<J> {
@Override
SubGraphImplementor<J> makeCopy(boolean mutable);

View File

@ -1064,7 +1064,8 @@ public class SessionImpl
final GraphSemantic semantic = effectiveEntityGraph.getSemantic();
final RootGraphImplementor<?> graph = effectiveEntityGraph.getGraph();
boolean clearedEffectiveGraph;
if ( semantic == null || graph.appliesTo( entityName, getFactory().getJpaMetamodel() ) ) {
if ( semantic == null
|| graph.appliesTo( getFactory().getJpaMetamodel().entity( entityName ) ) ) {
clearedEffectiveGraph = false;
}
else {

View File

@ -58,7 +58,6 @@ import org.hibernate.property.access.spi.Getter;
import org.hibernate.type.AnyType;
import org.hibernate.type.EntityType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.spi.CompositeTypeImplementor;
import jakarta.persistence.ManyToMany;
@ -99,7 +98,6 @@ public class AttributeFactory {
return buildAttribute( ownerType, property, context );
}
@SuppressWarnings("unchecked")
public static <X, Y> PersistentAttribute<X, Y> buildAttribute(
ManagedDomainType<X> ownerType,
Property property,
@ -118,9 +116,8 @@ public class AttributeFactory {
);
if ( attributeMetadata instanceof PluralAttributeMetadata ) {
//noinspection rawtypes
return PluralAttributeBuilder.build(
(PluralAttributeMetadata) attributeMetadata,
(PluralAttributeMetadata<X,Y,?>) attributeMetadata,
property.isGeneric(),
metadataContext
);
@ -175,20 +172,14 @@ public class AttributeFactory {
Property property) {
LOG.tracef( "Building identifier attribute [%s.%s]", ownerType.getTypeName(), property.getName() );
// ownerType = Entity(Person)
// MetadataContext#containerRoleStack -> Person
// id-attribute = "id"
final SingularAttributeMetadata<X, Y> attributeMetadata = (SingularAttributeMetadata<X,Y>) determineAttributeMetadata(
wrap( ownerType, property ),
identifierMemberResolver
);
final AttributeMetadata<X, Y> attributeMetadata =
determineAttributeMetadata( wrap( ownerType, property ), identifierMemberResolver );
final SingularAttributeMetadata<X, Y> singularAttributeMetadata = (SingularAttributeMetadata<X, Y>) attributeMetadata;
final DomainType<Y> domainType = determineSimpleType( singularAttributeMetadata.getValueContext() );
return new SingularAttributeImpl.Identifier<>(
ownerType,
property.getName(),
(SimpleDomainType<Y>) determineSimpleType( attributeMetadata.getValueContext() ),
(SimpleDomainType<Y>) domainType,
attributeMetadata.getMember(),
attributeMetadata.getAttributeClassification(),
property.isGeneric(),
@ -211,16 +202,15 @@ public class AttributeFactory {
Property property) {
LOG.tracef( "Building version attribute [%s.%s]", ownerType.getTypeName(), property.getName() );
final SingularAttributeMetadata<X, Y> attributeMetadata = (SingularAttributeMetadata<X, Y>) determineAttributeMetadata(
wrap( ownerType, property ),
versionMemberResolver
);
final AttributeMetadata<X, Y> attributeMetadata =
determineAttributeMetadata( wrap( ownerType, property ), versionMemberResolver );
final SingularAttributeMetadata<X, Y> singularAttributeMetadata = (SingularAttributeMetadata<X, Y>) attributeMetadata;
final DomainType<Y> domainType = determineSimpleType( singularAttributeMetadata.getValueContext() );
return new SingularAttributeImpl.Version<>(
ownerType,
property.getName(),
attributeMetadata.getAttributeClassification(),
(SimpleDomainType<Y>) determineSimpleType( attributeMetadata.getValueContext() ),
(SimpleDomainType<Y>) domainType,
attributeMetadata.getMember(),
context
);
@ -230,105 +220,117 @@ public class AttributeFactory {
return determineSimpleType( typeContext, context );
}
@SuppressWarnings("unchecked")
public static <Y> DomainType<Y> determineSimpleType(ValueContext typeContext, MetadataContext context) {
switch ( typeContext.getValueClassification() ) {
case BASIC: {
final Class<?> jpaBindableType = typeContext.getJpaBindableType();
if ( jpaBindableType.isPrimitive() ) {
// Special BasicDomainType necessary for primitive types in the JPA metamodel
return (DomainType<Y>) context.resolveBasicType( jpaBindableType );
}
return (DomainType<Y>) typeContext.getHibernateValue().getType();
}
case ENTITY: {
final org.hibernate.type.Type type = typeContext.getHibernateValue().getType();
if ( type instanceof EntityType ) {
final EntityType entityType = (EntityType) type;
final IdentifiableDomainType<Y> domainType =
context.locateIdentifiableType( entityType.getAssociatedEntityName() );
if ( domainType == null ) {
// Due to the use of generics, it can happen that a mapped super class uses a type
// for an attribute that is not a managed type. Since this case is not specifically mentioned
// in the Jakarta Persistence spec, we handle this by returning a "dummy" entity type
final JavaType<Y> domainJavaType = context.getJavaTypeRegistry().resolveDescriptor(
typeContext.getJpaBindableType()
);
return new EntityTypeImpl<>( domainJavaType, context.getJpaMetamodel() );
}
return domainType;
}
assert type instanceof AnyType;
final AnyType anyType = (AnyType) type;
final JavaType<Y> baseJtd = context.getTypeConfiguration()
.getJavaTypeRegistry()
.resolveDescriptor( anyType.getReturnedClass() );
return (DomainType<Y>) new AnyMappingDomainTypeImpl(
(Any) typeContext.getHibernateValue(),
anyType,
(JavaType<Class>) baseJtd,
context.getRuntimeModelCreationContext().getSessionFactory().getMappingMetamodel()
);
}
case EMBEDDABLE: {
final Component component = (Component) typeContext.getHibernateValue();
final EmbeddableTypeImpl<Y> embeddableType;
if ( component.isDynamic() ) {
final JavaType<Y> javaType = context.getJavaTypeRegistry().getDescriptor( java.util.Map.class );
embeddableType = new EmbeddableTypeImpl<>(
javaType,
true,
context.getJpaMetamodel()
);
context.registerComponentByEmbeddable( embeddableType, component );
}
else {
// we should have a non-dynamic embeddable
assert component.getComponentClassName() != null;
@SuppressWarnings("unchecked")
final Class<Y> embeddableClass = (Class<Y>) component.getComponentClass();
if ( !component.isGeneric() ) {
final EmbeddableDomainType<Y> cached = context.locateEmbeddable( embeddableClass, component );
if ( cached != null ) {
return cached;
}
}
final JavaTypeRegistry registry = context.getTypeConfiguration()
.getJavaTypeRegistry();
final JavaType<Y> javaType = registry.resolveManagedTypeDescriptor( embeddableClass );
embeddableType = new EmbeddableTypeImpl<>(
javaType,
false,
context.getJpaMetamodel()
);
context.registerEmbeddableType( embeddableType, component );
return embeddableType;
}
final EmbeddableTypeImpl.InFlightAccess<Y> inFlightAccess = embeddableType.getInFlightAccess();
for ( Property property : component.getProperties() ) {
final PersistentAttribute<Y, Y> attribute = buildAttribute( embeddableType, property, context );
if ( attribute != null ) {
inFlightAccess.addAttribute( attribute );
}
}
inFlightAccess.finishUp();
return embeddableType;
}
default: {
case BASIC:
return basicDomainType( typeContext, context );
case ENTITY:
return entityDomainType( typeContext, context );
case EMBEDDABLE:
return embeddableDomainType( typeContext, context );
default:
throw new AssertionFailure( "Unknown type : " + typeContext.getValueClassification() );
}
}
private static <Y> EmbeddableDomainType<Y> embeddableDomainType(ValueContext typeContext, MetadataContext context) {
final Component component = (Component) typeContext.getHibernateValue();
if ( component.isDynamic() ) {
return dynamicEmbeddableType( context, component );
}
else {
// we should have a non-dynamic embeddable
return classEmbeddableType( context, component );
}
}
private static <Y> EmbeddableDomainType<Y> classEmbeddableType(MetadataContext context, Component component) {
assert component.getComponentClassName() != null;
@SuppressWarnings("unchecked")
final Class<Y> embeddableClass = (Class<Y>) component.getComponentClass();
if ( !component.isGeneric() ) {
final EmbeddableDomainType<Y> cached = context.locateEmbeddable( embeddableClass, component);
if ( cached != null ) {
return cached;
}
}
final EmbeddableTypeImpl<Y> embeddableType = new EmbeddableTypeImpl<>(
context.getJavaTypeRegistry().resolveManagedTypeDescriptor( embeddableClass ),
false,
context.getJpaMetamodel()
);
context.registerEmbeddableType( embeddableType, component);
return embeddableType;
}
private static <Y> EmbeddableTypeImpl<Y> dynamicEmbeddableType(MetadataContext context, Component component) {
final EmbeddableTypeImpl<Y> embeddableType = new EmbeddableTypeImpl<>(
context.getJavaTypeRegistry().getDescriptor( java.util.Map.class ),
true,
context.getJpaMetamodel()
);
context.registerComponentByEmbeddable( embeddableType, component);
final EmbeddableTypeImpl.InFlightAccess<Y> inFlightAccess = embeddableType.getInFlightAccess();
for ( Property property : component.getProperties() ) {
final PersistentAttribute<Y, Y> attribute = buildAttribute( embeddableType, property, context);
if ( attribute != null ) {
inFlightAccess.addAttribute( attribute );
}
}
inFlightAccess.finishUp();
return embeddableType;
}
private static <Y> DomainType<Y> entityDomainType(ValueContext typeContext, MetadataContext context) {
final org.hibernate.type.Type type = typeContext.getHibernateValue().getType();
if ( type instanceof EntityType ) {
final EntityType entityType = (EntityType) type;
final IdentifiableDomainType<Y> domainType =
context.locateIdentifiableType( entityType.getAssociatedEntityName() );
if ( domainType == null ) {
// Due to the use of generics, it can happen that a mapped super class uses a type
// for an attribute that is not a managed type. Since this case is not specifically mentioned
// in the Jakarta Persistence spec, we handle this by returning a "dummy" entity type
final JavaType<Y> domainJavaType = context.getJavaTypeRegistry().resolveDescriptor(
typeContext.getJpaBindableType()
);
return new EntityTypeImpl<>(domainJavaType, context.getJpaMetamodel());
}
return domainType;
}
assert type instanceof AnyType;
final AnyType anyType = (AnyType) type;
final JavaType<Y> baseJtd = context.getTypeConfiguration()
.getJavaTypeRegistry()
.resolveDescriptor( anyType.getReturnedClass() );
return new AnyMappingDomainTypeImpl<>(
(Any) typeContext.getHibernateValue(),
anyType,
baseJtd,
context.getRuntimeModelCreationContext().getSessionFactory().getMappingMetamodel()
);
}
private static <Y> DomainType<Y> basicDomainType(ValueContext typeContext, MetadataContext context) {
if ( typeContext.getJpaBindableType().isPrimitive() ) {
// Special BasicDomainType necessary for primitive types in the JPA metamodel
@SuppressWarnings("unchecked")
final Class<Y> type = (Class<Y>) typeContext.getJpaBindableType();
return context.resolveBasicType(type);
}
else {
@SuppressWarnings("unchecked")
DomainType<Y> type = (DomainType<Y>) typeContext.getHibernateValue().getType();
return type;
}
}
private static JavaType<?> determineRelationalJavaType(

View File

@ -30,8 +30,8 @@ class PluralAttributeMetadataImpl<X, Y, E>
private final CollectionClassification collectionClassification;
private final AttributeClassification elementClassification;
private final AttributeClassification listIndexOrMapKeyClassification;
private final Class elementJavaType;
private final Class keyJavaType;
private final Class<?> elementJavaType;
private final Class<?> keyJavaType;
private final ValueContext elementValueContext;
private final ValueContext keyValueContext;
@ -86,7 +86,7 @@ class PluralAttributeMetadataImpl<X, Y, E>
return ( (Collection) getPropertyMapping().getValue() ).getElement();
}
public Class getJpaBindableType() {
public Class<?> getJpaBindableType() {
return elementJavaType;
}
@ -104,7 +104,7 @@ class PluralAttributeMetadataImpl<X, Y, E>
}
}
public AttributeMetadata getAttributeMetadata() {
public AttributeMetadata<X,Y> getAttributeMetadata() {
return PluralAttributeMetadataImpl.this;
}
};
@ -116,7 +116,7 @@ class PluralAttributeMetadataImpl<X, Y, E>
return ( (Map) getPropertyMapping().getValue() ).getIndex();
}
public Class getJpaBindableType() {
public Class<?> getJpaBindableType() {
return keyJavaType;
}
@ -134,7 +134,7 @@ class PluralAttributeMetadataImpl<X, Y, E>
}
}
public AttributeMetadata getAttributeMetadata() {
public AttributeMetadata<X,Y> getAttributeMetadata() {
return PluralAttributeMetadataImpl.this;
}
};
@ -146,10 +146,10 @@ class PluralAttributeMetadataImpl<X, Y, E>
private Class<?> getClassFromGenericArgument(java.lang.reflect.Type type) {
if ( type instanceof Class ) {
return (Class) type;
return (Class<?>) type;
}
else if ( type instanceof TypeVariable ) {
final java.lang.reflect.Type upperBound = ( (TypeVariable) type ).getBounds()[0];
final java.lang.reflect.Type upperBound = ( (TypeVariable<?>) type ).getBounds()[0];
return getClassFromGenericArgument( upperBound );
}
else if ( type instanceof ParameterizedType ) {
@ -168,7 +168,7 @@ class PluralAttributeMetadataImpl<X, Y, E>
}
}
public static CollectionClassification determineCollectionType(Class javaType, Property property) {
public static CollectionClassification determineCollectionType(Class<?> javaType, Property property) {
final Collection collection = (Collection) property.getValue();
if ( java.util.List.class.isAssignableFrom( javaType ) ) {

View File

@ -33,7 +33,7 @@ public class SingularAttributeMetadataImpl<X, Y> extends BaseAttributeMetadata<X
return getPropertyMapping().getValue();
}
public Class getJpaBindableType() {
public Class<Y> getJpaBindableType() {
return getAttributeMetadata().getJavaType();
}
@ -51,7 +51,7 @@ public class SingularAttributeMetadataImpl<X, Y> extends BaseAttributeMetadata<X
}
}
public AttributeMetadata getAttributeMetadata() {
public AttributeMetadata<X,Y> getAttributeMetadata() {
return SingularAttributeMetadataImpl.this;
}
};

View File

@ -17,7 +17,7 @@ public interface ValueContext {
Value getHibernateValue();
Class getJpaBindableType();
Class<?> getJpaBindableType();
AttributeMetadata getAttributeMetadata();
AttributeMetadata<?,?> getAttributeMetadata();
}

View File

@ -15,6 +15,6 @@ package org.hibernate.metamodel.model.domain;
* @author Steve Ebersole
*/
public interface AnyMappingDomainType<J> extends SimpleDomainType<J> {
SimpleDomainType getDiscriminatorType();
SimpleDomainType getKeyType();
SimpleDomainType<?> getDiscriminatorType();
SimpleDomainType<?> getKeyType();
}

View File

@ -13,7 +13,7 @@ import jakarta.persistence.metamodel.EntityType;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Extension to the JPA {@link EntityType} contract
* Extension to the JPA {@link EntityType} contract.
*
* @author Steve Ebersole
*/

View File

@ -15,7 +15,7 @@ import jakarta.persistence.metamodel.SingularAttribute;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Extension to the JPA {@link IdentifiableType} contract
* Extension to the JPA {@link IdentifiableType} contract.
*
* @author Steve Ebersole
*/

View File

@ -14,10 +14,7 @@ import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Hibernate extension to the JPA {@link PluralAttribute} descriptor
*
* todo (6.0) : Create an form of plural attribute (and singular) in the API package (org.hibernate.metamodel.model.domain)
* and have this extend it
* Extension of the JPA-defined {@link PluralAttribute} interface.
*
* @author Steve Ebersole
*/

View File

@ -12,12 +12,12 @@ import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Hibernate extension to the JPA {@link SingularAttribute} descriptor
* Extension of the JPA-defined {@link SingularAttribute} interface.
*
* @author Steve Ebersole
*/
public interface SingularPersistentAttribute<D,J>
extends SingularAttribute<D,J>, PersistentAttribute<D,J>, SqmPathSource<J>, SqmJoinable {
extends SingularAttribute<D,J>, PersistentAttribute<D,J>, SqmPathSource<J>, SqmJoinable<D,J> {
@Override
SimpleDomainType<J> getType();

View File

@ -24,6 +24,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
import org.hibernate.type.descriptor.java.JavaType;
import static jakarta.persistence.metamodel.Bindable.BindableType.PLURAL_ATTRIBUTE;
import static org.hibernate.query.sqm.spi.SqmCreationHelper.buildSubNavigablePath;
/**
@ -59,7 +60,7 @@ public abstract class AbstractPluralAttribute<D, C, E>
this.elementPathSource = SqmMappingModelHelper.resolveSqmPathSource(
CollectionPart.Nature.ELEMENT.getName(),
builder.getValueType(),
BindableType.PLURAL_ATTRIBUTE,
PLURAL_ATTRIBUTE,
builder.isGeneric()
);
}
@ -134,7 +135,7 @@ public abstract class AbstractPluralAttribute<D, C, E>
@Override
public boolean isAssociation() {
return getPersistentAttributeType() == PersistentAttributeType.ONE_TO_MANY
|| getPersistentAttributeType() == PersistentAttributeType.MANY_TO_MANY;
|| getPersistentAttributeType() == PersistentAttributeType.MANY_TO_MANY;
}
@Override
@ -144,7 +145,7 @@ public abstract class AbstractPluralAttribute<D, C, E>
@Override
public BindableType getBindableType() {
return BindableType.PLURAL_ATTRIBUTE;
return PLURAL_ATTRIBUTE;
}
@Override
@ -154,15 +155,8 @@ public abstract class AbstractPluralAttribute<D, C, E>
@Override
public SqmPath<E> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
final NavigablePath navigablePath;
if ( intermediatePathSource == null ) {
navigablePath = lhs.getNavigablePath().append( getPathName() );
}
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
return new SqmPluralValuedSimplePath<>(
navigablePath,
PathHelper.append( lhs, this, intermediatePathSource ),
this,
lhs,
lhs.nodeBuilder()

View File

@ -41,7 +41,7 @@ public abstract class AbstractSqmPathSource<J> implements SqmPathSource<J> {
}
@Override
public DomainType<?> getSqmPathType() {
public DomainType<J> getSqmPathType() {
return domainType;
}

View File

@ -16,7 +16,7 @@ import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
/**
* SqmPathSource implementation for {@link org.hibernate.annotations.AnyDiscriminator}
* {@link SqmPathSource} implementation for {@link org.hibernate.annotations.AnyDiscriminator}
*
*/
public class AnyDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
@ -39,7 +39,7 @@ public class AnyDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() );
}
return new AnyDiscriminatorSqmPath( navigablePath, pathModel, lhs, lhs.nodeBuilder() );
return new AnyDiscriminatorSqmPath<>( navigablePath, pathModel, lhs, lhs.nodeBuilder() );
}
@Override

View File

@ -26,16 +26,16 @@ import java.util.List;
/**
* @author Steve Ebersole
*/
public class AnyMappingDomainTypeImpl implements AnyMappingDomainType<Class> {
public class AnyMappingDomainTypeImpl<T> implements AnyMappingDomainType<T> {
private final AnyType anyType;
private final JavaType<Class> baseJtd;
private final BasicType<Class> anyDiscriminatorType;
private final JavaType<T> baseJtd;
private final BasicType<Class<?>> anyDiscriminatorType;
@SuppressWarnings({ "unchecked", "rawtypes" })
public AnyMappingDomainTypeImpl(
Any bootAnyMapping,
AnyType anyType,
JavaType<Class> baseJtd,
JavaType<T> baseJtd,
MappingMetamodelImplementor mappingMetamodel) {
this.anyType = anyType;
this.baseJtd = baseJtd;
@ -90,23 +90,22 @@ public class AnyMappingDomainTypeImpl implements AnyMappingDomainType<Class> {
}
@Override
@SuppressWarnings("unchecked")
public Class<Class> getJavaType() {
return (Class<Class>) anyType.getReturnedClass();
public Class<T> getJavaType() {
return baseJtd.getJavaTypeClass();
}
@Override
public JavaType<Class> getExpressibleJavaType() {
public JavaType<T> getExpressibleJavaType() {
return baseJtd;
}
@Override
public BasicType<Class> getDiscriminatorType() {
public BasicType<Class<?>> getDiscriminatorType() {
return anyDiscriminatorType;
}
@Override
public SimpleDomainType getKeyType() {
public SimpleDomainType<?> getKeyType() {
return (BasicType<?>) anyType.getIdentifierType();
}

View File

@ -11,7 +11,6 @@ import org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart;
import org.hibernate.metamodel.mapping.internal.AnyKeyPart;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -23,7 +22,7 @@ import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRI
*/
public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
private final SqmPathSource<?> keyPathSource;
private final AnyDiscriminatorSqmPathSource discriminatorPathSource;
private final AnyDiscriminatorSqmPathSource<?> discriminatorPathSource;
public AnyMappingSqmPathSource(
String localPathName,
@ -47,7 +46,7 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
);
}
@Override @SuppressWarnings("unchecked")
@Override
public AnyMappingDomainType<J> getSqmPathType() {
return (AnyMappingDomainType<J>) super.getSqmPathType();
}
@ -68,13 +67,11 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
final NavigablePath navigablePath;
if ( intermediatePathSource == null ) {
navigablePath = lhs.getNavigablePath().append( getPathName() );
}
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
return new SqmAnyValuedSimplePath<>( navigablePath, pathModel, lhs, lhs.nodeBuilder() );
return new SqmAnyValuedSimplePath<>(
PathHelper.append( lhs, this, intermediatePathSource ),
pathModel,
lhs,
lhs.nodeBuilder()
);
}
}

View File

@ -33,14 +33,13 @@ public class BagAttributeImpl<X, E>
}
@Override
public SqmAttributeJoin createSqmJoin(
SqmFrom lhs,
public SqmAttributeJoin<X,E> createSqmJoin(
SqmFrom<?,X> lhs,
SqmJoinType joinType,
String alias,
boolean fetched,
SqmCreationState creationState) {
//noinspection unchecked
return new SqmBagJoin(
return new SqmBagJoin<>(
lhs,
this,
alias,

View File

@ -13,7 +13,6 @@ import org.hibernate.query.sqm.TerminalPathException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.spi.NavigablePath;
import org.hibernate.type.descriptor.java.JavaType;
/**
@ -39,7 +38,6 @@ public class BasicSqmPathSource<J>
@Override
public BasicDomainType<J> getSqmPathType() {
//noinspection unchecked
return (BasicDomainType<J>) super.getSqmPathType();
}
@ -57,15 +55,8 @@ public class BasicSqmPathSource<J>
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
final NavigablePath navigablePath;
if ( intermediatePathSource == null ) {
navigablePath = lhs.getNavigablePath().append( getPathName() );
}
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
return new SqmBasicValuedSimplePath<>(
navigablePath,
PathHelper.append( lhs, this, intermediatePathSource ),
pathModel,
lhs,
lhs.nodeBuilder()

View File

@ -6,15 +6,16 @@
*/
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.ReturnableType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRIBUTE;
import static org.hibernate.metamodel.mapping.EntityDiscriminatorMapping.DISCRIMINATOR_ROLE_NAME;
/**
* SqmPathSource implementation for entity discriminator
*
@ -29,7 +30,7 @@ public class DiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
DomainType<D> discriminatorValueType,
EntityDomainType<?> entityDomainType,
EntityMappingType entityMapping) {
super( EntityDiscriminatorMapping.DISCRIMINATOR_ROLE_NAME, null, discriminatorValueType, BindableType.SINGULAR_ATTRIBUTE );
super( DISCRIMINATOR_ROLE_NAME, null, discriminatorValueType, SINGULAR_ATTRIBUTE );
this.entityDomainType = entityDomainType;
this.entityMapping = entityMapping;
}
@ -44,14 +45,14 @@ public class DiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
@Override
public SqmPath<D> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
final NavigablePath navigablePath;
if ( intermediatePathSource == null ) {
navigablePath = lhs.getNavigablePath().append( getPathName() );
}
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
return new EntityDiscriminatorSqmPath( navigablePath, pathModel, lhs, entityDomainType, entityMapping, lhs.nodeBuilder() );
return new EntityDiscriminatorSqmPath<>(
PathHelper.append( lhs, this, intermediatePathSource ),
pathModel,
lhs,
entityDomainType,
entityMapping,
lhs.nodeBuilder()
);
}
@Override

View File

@ -10,7 +10,6 @@ import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.spi.NavigablePath;
/**
* @author Steve Ebersole
@ -32,7 +31,6 @@ public class EmbeddedSqmPathSource<J>
@Override
public EmbeddableDomainType<J> getSqmPathType() {
//noinspection unchecked
return (EmbeddableDomainType<J>) super.getSqmPathType();
}
@ -48,15 +46,8 @@ public class EmbeddedSqmPathSource<J>
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
final NavigablePath navigablePath;
if ( intermediatePathSource == null ) {
navigablePath = lhs.getNavigablePath().append( getPathName() );
}
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
return new SqmEmbeddedValuedSimplePath<>(
navigablePath,
PathHelper.append( lhs, this, intermediatePathSource ),
pathModel,
lhs,
lhs.nodeBuilder()

View File

@ -7,6 +7,7 @@
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.model.domain.DiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
@ -18,12 +19,12 @@ import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
import org.hibernate.spi.NavigablePath;
/**
* SqmPath specialization for an entity discriminator
* {@link SqmPath} specialization for an entity discriminator
*
* @author Steve Ebersole
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class EntityDiscriminatorSqmPath extends AbstractSqmPath implements org.hibernate.metamodel.model.domain.DiscriminatorSqmPath {
public class EntityDiscriminatorSqmPath<T> extends AbstractSqmPath<T> implements DiscriminatorSqmPath<T> {
private final EntityDomainType entityDomainType;
private final EntityMappingType entityDescriptor;

View File

@ -8,7 +8,6 @@ package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource;
@ -36,7 +35,6 @@ public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> implements
@Override
public EntityDomainType<J> getSqmPathType() {
//noinspection unchecked
return (EntityDomainType<J>) super.getSqmPathType();
}
@ -57,15 +55,8 @@ public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> implements
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
final NavigablePath navigablePath;
if ( intermediatePathSource == null ) {
navigablePath = lhs.getNavigablePath().append( getPathName() );
}
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
return new SqmEntityValuedSimplePath<>(
navigablePath,
PathHelper.append( lhs, this, intermediatePathSource ),
pathModel,
lhs,
lhs.nodeBuilder()

View File

@ -265,24 +265,19 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
public <T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Class<T> entityClass) {
final EntityDomainType<T> entityType = entity( entityClass );
if ( entityType == null ) {
throw new IllegalArgumentException( "Given class is not an entity : " + entityClass.getName() );
throw new IllegalArgumentException( "Given class is not an entity: " + entityClass.getName() );
}
final List<RootGraphImplementor<? super T>> results = new ArrayList<>();
for ( EntityGraph<?> entityGraph : entityGraphMap.values() ) {
if ( !( entityGraph instanceof RootGraphImplementor ) ) {
continue;
}
//noinspection unchecked
final RootGraphImplementor<T> egi = (RootGraphImplementor<T>) entityGraph;
if ( egi.appliesTo( entityType, this ) ) {
results.add( egi );
else {
final List<RootGraphImplementor<? super T>> results = new ArrayList<>();
for ( RootGraphImplementor<?> entityGraph : entityGraphMap.values() ) {
if ( entityGraph.appliesTo( entityType ) ) {
@SuppressWarnings("unchecked")
final RootGraphImplementor<? super T> result = (RootGraphImplementor<? super T>) entityGraph;
results.add( result );
}
}
return results;
}
return results;
}
@Override

View File

@ -79,18 +79,17 @@ public class ListAttributeImpl<X, E> extends AbstractPluralAttribute<X, List<E>,
public SqmPathSource<?> getIntermediatePathSource(SqmPathSource<?> pathSource) {
final String pathName = pathSource.getPathName();
return pathName.equals( getElementPathSource().getPathName() )
|| pathName.equals( indexPathSource.getPathName() ) ? null : getElementPathSource();
|| pathName.equals( indexPathSource.getPathName() ) ? null : getElementPathSource();
}
@Override
public SqmAttributeJoin createSqmJoin(
SqmFrom lhs,
public SqmAttributeJoin<X,E> createSqmJoin(
SqmFrom<?,X> lhs,
SqmJoinType joinType,
String alias,
boolean fetched,
SqmCreationState creationState) {
//noinspection unchecked
return new SqmListJoin(
return new SqmListJoin<>(
lhs,
this,
alias,

View File

@ -103,9 +103,9 @@ public class MapAttributeImpl<X, K, V> extends AbstractPluralAttribute<X, Map<K,
}
@Override
public SqmAttributeJoin createSqmJoin(
SqmFrom lhs, SqmJoinType joinType, String alias, boolean fetched, SqmCreationState creationState) {
return new SqmMapJoin(
public SqmAttributeJoin<X,V> createSqmJoin(
SqmFrom<?,X> lhs, SqmJoinType joinType, String alias, boolean fetched, SqmCreationState creationState) {
return new SqmMapJoin<>(
lhs,
this,
alias,

View File

@ -8,7 +8,6 @@ package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmJoinType;
@ -31,8 +30,7 @@ public class MappedSuperclassSqmPathSource<J> extends AbstractSqmPathSource<J> i
@Override
public MappedSuperclassDomainType<J> getSqmPathType() {
//noinspection unchecked
return ( MappedSuperclassDomainType<J> ) super.getSqmPathType();
return (MappedSuperclassDomainType<J>) super.getSqmPathType();
}
@Override
@ -43,15 +41,8 @@ public class MappedSuperclassSqmPathSource<J> extends AbstractSqmPathSource<J> i
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
final NavigablePath navigablePath;
if ( intermediatePathSource == null ) {
navigablePath = lhs.getNavigablePath().append( getPathName() );
}
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
return new SqmEntityValuedSimplePath<>(
navigablePath,
PathHelper.append( lhs, this, intermediatePathSource ),
pathModel,
lhs,
lhs.nodeBuilder()

View File

@ -7,7 +7,6 @@
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.NonAggregatedCompositeSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -27,8 +26,8 @@ public class NonAggregatedCompositeSqmPathSource<J> extends AbstractSqmPathSourc
}
@Override
public ManagedDomainType<?> getSqmPathType() {
return (ManagedDomainType<?>) super.getSqmPathType();
public ManagedDomainType<J> getSqmPathType() {
return (ManagedDomainType<J>) super.getSqmPathType();
}
@Override
@ -38,15 +37,8 @@ public class NonAggregatedCompositeSqmPathSource<J> extends AbstractSqmPathSourc
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
final NavigablePath navigablePath;
if ( intermediatePathSource == null ) {
navigablePath = lhs.getNavigablePath().append( getPathName() );
}
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
return new NonAggregatedCompositeSimplePath<>(
navigablePath,
PathHelper.append( lhs, this, intermediatePathSource ),
pathModel,
lhs,
lhs.nodeBuilder()

View File

@ -0,0 +1,19 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.spi.NavigablePath;
public class PathHelper {
public static NavigablePath append(SqmPath<?> lhs, SqmPathSource<?> rhs, SqmPathSource<?> intermediatePathSource) {
return intermediatePathSource == null
? lhs.getNavigablePath().append( rhs.getPathName() )
: lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( rhs.getPathName() );
}
}

View File

@ -32,7 +32,7 @@ import static org.hibernate.metamodel.internal.AttributeFactory.determineSimpleT
*/
public class PluralAttributeBuilder<D, C, E, K> {
private final JavaType<C> collectionJtd;
private boolean isGeneric;
private final boolean isGeneric;
private final AttributeClassification attributeClassification;
private final CollectionClassification collectionClassification;

View File

@ -31,9 +31,9 @@ public class SetAttributeImpl<X, E> extends AbstractPluralAttribute<X, Set<E>, E
}
@Override
public SqmAttributeJoin createSqmJoin(
SqmFrom lhs, SqmJoinType joinType, String alias, boolean fetched, SqmCreationState creationState) {
return new SqmSetJoin(
public SqmAttributeJoin<X, E> createSqmJoin(
SqmFrom<?,X> lhs, SqmJoinType joinType, String alias, boolean fetched, SqmCreationState creationState) {
return new SqmSetJoin<>(
lhs,
this,
alias,

View File

@ -8,9 +8,7 @@ package org.hibernate.metamodel.model.domain.internal;
import java.io.Serializable;
import java.lang.reflect.Member;
import java.util.function.Supplier;
import org.hibernate.graph.spi.GraphHelper;
import org.hibernate.metamodel.AttributeClassification;
import org.hibernate.metamodel.internal.MetadataContext;
import org.hibernate.metamodel.mapping.CollectionPart;
@ -37,6 +35,7 @@ import org.hibernate.spi.EntityIdentifierNavigablePath;
import org.hibernate.spi.NavigablePath;
import org.hibernate.type.descriptor.java.JavaType;
import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRIBUTE;
import static org.hibernate.query.sqm.spi.SqmCreationHelper.buildSubNavigablePath;
/**
@ -52,9 +51,6 @@ public class SingularAttributeImpl<D,J>
private final SqmPathSource<J> sqmPathSource;
// NOTE : delay access for timing reasons
private final DelayedKeyTypeAccess graphKeyTypeAccess = new DelayedKeyTypeAccess();
public SingularAttributeImpl(
ManagedDomainType<D> declaringType,
String name,
@ -86,7 +82,7 @@ public class SingularAttributeImpl<D,J>
this,
attributeType,
relationalJavaType,
BindableType.SINGULAR_ATTRIBUTE,
SINGULAR_ATTRIBUTE,
isGeneric
);
}
@ -102,7 +98,6 @@ public class SingularAttributeImpl<D,J>
@Override
public SimpleDomainType<J> getSqmPathType() {
//noinspection unchecked
return (SimpleDomainType<J>) sqmPathSource.getSqmPathType();
}
@ -112,8 +107,11 @@ public class SingularAttributeImpl<D,J>
}
@Override
public SimpleDomainType<J> getKeyGraphType() {
return graphKeyTypeAccess.get();
public SimpleDomainType<?> getKeyGraphType() {
final SimpleDomainType<?> attributeType = getType();
return attributeType instanceof IdentifiableDomainType
? ( (IdentifiableDomainType<?>) attributeType ).getIdType()
: null;
}
@Override
@ -148,7 +146,7 @@ public class SingularAttributeImpl<D,J>
@Override
public SqmAttributeJoin<D,J> createSqmJoin(
SqmFrom lhs,
SqmFrom<?,D> lhs,
SqmJoinType joinType,
String alias,
boolean fetched,
@ -156,20 +154,20 @@ public class SingularAttributeImpl<D,J>
if ( getType() instanceof AnyMappingDomainType ) {
throw new SemanticException( "An @Any attribute cannot be join fetched" );
}
//noinspection unchecked
return new SqmSingularJoin<D,J>(
lhs,
this,
alias,
joinType,
fetched,
creationState.getCreationContext().getNodeBuilder()
);
else {
return new SqmSingularJoin<>(
lhs,
this,
alias,
joinType,
fetched,
creationState.getCreationContext().getNodeBuilder()
);
}
}
@Override
public NavigablePath createNavigablePath(SqmPath parent, String alias) {
public NavigablePath createNavigablePath(SqmPath<?> parent, String alias) {
if ( parent == null ) {
throw new IllegalArgumentException(
"LHS cannot be null for a sub-navigable reference - " + getName()
@ -219,7 +217,7 @@ public class SingularAttributeImpl<D,J>
}
@Override
public NavigablePath createNavigablePath(SqmPath parent, String alias) {
public NavigablePath createNavigablePath(SqmPath<?> parent, String alias) {
if ( parent == null ) {
throw new IllegalArgumentException(
"LHS cannot be null for a sub-navigable reference - " + getName()
@ -296,25 +294,11 @@ public class SingularAttributeImpl<D,J>
@Override
public BindableType getBindableType() {
return BindableType.SINGULAR_ATTRIBUTE;
return SINGULAR_ATTRIBUTE;
}
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
return sqmPathSource.createSqmPath( lhs, intermediatePathSource );
}
private class DelayedKeyTypeAccess implements Supplier<SimpleDomainType<J>>, Serializable {
private boolean resolved;
private SimpleDomainType<J> type;
@Override
public SimpleDomainType<J> get() {
if ( ! resolved ) {
type = GraphHelper.resolveKeyTypeDescriptor( SingularAttributeImpl.this );
resolved = true;
}
return type;
}
}
}

View File

@ -3617,7 +3617,8 @@ public abstract class AbstractEntityPersister
@Override
public boolean isAffectedByEntityGraph(LoadQueryInfluencers loadQueryInfluencers) {
final RootGraphImplementor<?> graph = loadQueryInfluencers.getEffectiveEntityGraph().getGraph();
return graph != null && graph.appliesTo( getEntityName(), getFactory().getJpaMetamodel() );
return graph != null
&& graph.appliesTo( getFactory().getJpaMetamodel().entity( getEntityName() ) );
}
@Override

View File

@ -29,7 +29,7 @@ public interface JpaOrder extends Order, JpaCriteriaNode {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Co-variants
// Covariant returns
@Override
JpaOrder reverse();

View File

@ -8,10 +8,10 @@ package org.hibernate.query.derived;
import org.hibernate.Incubating;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.internal.PathHelper;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.spi.NavigablePath;
import org.hibernate.type.descriptor.java.JavaType;
/**
@ -43,7 +43,7 @@ public class AnonymousTupleSimpleSqmPathSource<J> implements SqmPathSource<J> {
}
@Override
public DomainType<?> getSqmPathType() {
public DomainType<J> getSqmPathType() {
return domainType;
}
@ -64,15 +64,8 @@ public class AnonymousTupleSimpleSqmPathSource<J> implements SqmPathSource<J> {
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
final NavigablePath navigablePath;
if ( intermediatePathSource == null ) {
navigablePath = lhs.getNavigablePath().append( getPathName() );
}
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
return new SqmBasicValuedSimplePath<>(
navigablePath,
PathHelper.append( lhs, this, intermediatePathSource ),
this,
lhs,
lhs.nodeBuilder()

View File

@ -40,8 +40,8 @@ public class AnonymousTupleSqmAssociationPathSource<O, J> extends AnonymousTuple
}
@Override
public SqmJoin createSqmJoin(
SqmFrom lhs,
public SqmJoin<O, J> createSqmJoin(
SqmFrom<?, O> lhs,
SqmJoinType joinType,
String alias,
boolean fetched,

View File

@ -11,17 +11,12 @@ import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource;
import org.hibernate.metamodel.model.domain.internal.EmbeddedSqmPathSource;
import org.hibernate.metamodel.model.domain.internal.EntitySqmPathSource;
import org.hibernate.metamodel.model.domain.internal.PathHelper;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.spi.NavigablePath;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
/**
@ -51,8 +46,7 @@ public class AnonymousTupleSqmPathSource<J> implements SqmPathSource<J> {
@Override
public DomainType<J> getSqmPathType() {
//noinspection unchecked
return (DomainType<J>) path.getNodeType().getSqmPathType();
return path.getNodeType().getSqmPathType();
}
@Override
@ -72,17 +66,10 @@ public class AnonymousTupleSqmPathSource<J> implements SqmPathSource<J> {
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
final NavigablePath navigablePath;
if ( intermediatePathSource == null ) {
navigablePath = lhs.getNavigablePath().append( getPathName() );
}
else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
}
final DomainType<?> domainType = path.getNodeType().getSqmPathType();
if ( domainType instanceof BasicDomainType<?> ) {
return new SqmBasicValuedSimplePath<>(
navigablePath,
PathHelper.append( lhs, this, intermediatePathSource ),
this,
lhs,
lhs.nodeBuilder()
@ -90,7 +77,7 @@ public class AnonymousTupleSqmPathSource<J> implements SqmPathSource<J> {
}
else if ( domainType instanceof EmbeddableDomainType<?> ) {
return new SqmEmbeddedValuedSimplePath<>(
navigablePath,
PathHelper.append( lhs, this, intermediatePathSource ),
this,
lhs,
lhs.nodeBuilder()
@ -98,7 +85,7 @@ public class AnonymousTupleSqmPathSource<J> implements SqmPathSource<J> {
}
else if ( domainType instanceof EntityDomainType<?> ) {
return new SqmEntityValuedSimplePath<>(
navigablePath,
PathHelper.append( lhs, this, intermediatePathSource ),
this,
lhs,
lhs.nodeBuilder()

View File

@ -236,7 +236,7 @@ public class AnonymousTupleType<T> implements TupleType<T>, DomainType<T>, Retur
}
@Override
public DomainType<?> getSqmPathType() {
public DomainType<T> getSqmPathType() {
return this;
}

View File

@ -28,16 +28,18 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
*/
public interface SqmPathSource<J> extends SqmExpressible<J>, Bindable<J>, SqmExpressibleAccessor<J> {
/**
* The name of this thing. Mainly used in logging and when creating a
* {@link NavigablePath}
* The name of this thing.
*
* @apiNote Mainly used in logging and when creating a {@link NavigablePath}.
*/
String getPathName();
/**
* The type of SqmPaths this source creates. Corollary to JPA's
* {@link Bindable#getBindableJavaType()}
* The type of {@linkplain SqmPath path} this source creates.
*
* @apiNote Analogous to {@link Bindable#getBindableJavaType()}.
*/
DomainType<?> getSqmPathType();
DomainType<J> getSqmPathType();
/**
* Find a {@link SqmPathSource} by name relative to this source.

View File

@ -136,7 +136,7 @@ public class SqmPolymorphicRootDescriptor<T> implements EntityDomainType<T> {
}
@Override
public DomainType<?> getSqmPathType() {
public DomainType<T> getSqmPathType() {
return this;
}

View File

@ -160,7 +160,7 @@ public class NavigablePath implements DotIdentifierSequence, Serializable {
protected boolean localNamesMatch(EntityIdentifierNavigablePath other) {
return Objects.equals( getLocalName(), other.getLocalName() )
|| Objects.equals( getLocalName(), other.getIdentifierAttributeName() );
|| Objects.equals( getLocalName(), other.getIdentifierAttributeName() );
}
public NavigablePath append(String property) {

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.sql.results.graph.entity;
import org.hibernate.graph.spi.GraphHelper;
import org.hibernate.graph.spi.GraphImplementor;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
@ -43,9 +44,7 @@ public interface EntityResultGraphNode extends DomainResultGraphNode, FetchParen
@Override
default boolean appliesTo(GraphImplementor<?> graphImplementor, JpaMetamodel metamodel) {
return graphImplementor.appliesTo(
getEntityValuedModelPart().getEntityMappingType().getJavaType().getJavaTypeClass(),
metamodel
);
final String entityName = getEntityValuedModelPart().getEntityMappingType().getEntityName();
return GraphHelper.appliesTo( graphImplementor, metamodel.entity( entityName ) );
}
}

View File

@ -12,6 +12,7 @@ import jakarta.persistence.EntityManager;
import org.hibernate.graph.EntityGraphs;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.testing.TestForIssue;
import org.junit.Assert;
import org.junit.Ignore;
@ -198,6 +199,7 @@ public class EntityGraphsTest extends AbstractEntityGraphTest {
@TestForIssue( jiraKey = "HHH-14264" )
public void testRootGraphAppliesToChildEntityClass() {
RootGraphImplementor<GraphParsingTestEntity> rootGraphImplementor = parseGraph( GraphParsingTestEntity.class, "name, description" );
Assert.assertTrue( rootGraphImplementor.appliesTo( GraphParsingTestSubentity.class, entityManagerFactory().getJpaMetamodel() ) );
EntityDomainType<?> entity = entityManagerFactory().getJpaMetamodel().entity( (Class<?>) GraphParsingTestSubentity.class );
Assert.assertTrue( rootGraphImplementor.appliesTo( entity ) );
}
}