6 - SQM based on JPA type system

This commit is contained in:
Steve Ebersole 2019-05-22 17:53:46 -05:00 committed by Andrea Boriero
parent 3958e37103
commit af2c32e32c
90 changed files with 2242 additions and 1703 deletions

View File

@ -0,0 +1,48 @@
/*
* 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.collection.spi;
import java.util.Iterator;
import java.util.function.Consumer;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.persister.collection.CollectionPersister;
/**
* Describes the semantics of a persistent collection such that Hibernate
* understands how to use it - create one, handle elements, etc.
*
* @apiNote The described collection need not be part of the "Java Collection Framework"
*
* @author Steve Ebersole
* @author Gavin King
*/
public interface CollectionSemantics<C> {
/**
* Get the classification of collections described by this semantic
*/
CollectionClassification getCollectionClassification();
<E> C instantiateRaw(
int anticipatedSize,
CollectionPersister collectionDescriptor);
<E> PersistentCollection instantiateWrapper(
Object key,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session);
<E> PersistentCollection wrap(
Object rawCollection,
CollectionPersister collectionDescriptor,
SharedSessionContractImplementor session);
<E> Iterator<E> getElementIterator(C rawCollection);
void visitElements(C rawCollection, Consumer action);
}

View File

@ -51,13 +51,9 @@ import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter;
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
import org.hibernate.type.descriptor.sql.JdbcTypeJavaClassMappings;
import org.hibernate.type.descriptor.sql.LobTypeMappings;
import org.hibernate.type.descriptor.sql.NationalizedTypeMappings;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.DynamicParameterizedType;
/**

View File

@ -4,7 +4,7 @@
* 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;
package org.hibernate.metamodel;
import javax.persistence.metamodel.Attribute.PersistentAttributeType;

View File

@ -0,0 +1,17 @@
/*
* 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;
/**
* @author Steve Ebersole
*/
public enum ValueClassification {
BASIC,
ANY,
EMBEDDED,
ENTITY
}

View File

@ -29,7 +29,7 @@ import org.hibernate.mapping.OneToMany;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Value;
import org.hibernate.metamodel.model.AttributeClassification;
import org.hibernate.metamodel.AttributeClassification;
import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
@ -38,7 +38,6 @@ import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.internal.BasicTypeImpl;
import org.hibernate.metamodel.model.domain.internal.EmbeddableTypeImpl;
import org.hibernate.metamodel.model.domain.internal.MapMember;
import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
@ -107,7 +106,8 @@ public class AttributeFactory {
attributeMetadata.getMember(),
false,
false,
property.isOptional()
property.isOptional(),
context.getSessionFactory().getQueryEngine().getCriteriaBuilder()
);
}
@ -149,7 +149,8 @@ public class AttributeFactory {
property.getName(),
determineSimpleType( attributeMetadata.getValueContext() ),
attributeMetadata.getMember(),
attributeMetadata.getAttributeClassification()
attributeMetadata.getAttributeClassification(),
context.getSessionFactory().getQueryEngine().getCriteriaBuilder()
);
}
@ -179,7 +180,8 @@ public class AttributeFactory {
property.getName(),
attributeMetadata.getAttributeClassification(),
determineSimpleType( attributeMetadata.getValueContext() ),
attributeMetadata.getMember()
attributeMetadata.getMember(),
context.getSessionFactory().getQueryEngine().getCriteriaBuilder()
);
}
@ -195,9 +197,8 @@ public class AttributeFactory {
attributeMetadata.getOwnerType(),
determineSimpleType( attributeMetadata.getElementValueContext() ),
javaTypeDescriptor,
java.util.Map.class.isAssignableFrom( attributeMetadata.getJavaType() )
? determineSimpleType( attributeMetadata.getMapKeyValueContext() )
: null
determineListIndexOrMapKeyType( attributeMetadata ),
context.getSessionFactory().getQueryEngine().getCriteriaBuilder()
);
return info
@ -207,16 +208,24 @@ public class AttributeFactory {
.build();
}
private <X, Y, E> SimpleDomainType determineListIndexOrMapKeyType(PluralAttributeMetadata<X, Y, E> attributeMetadata) {
if ( java.util.Map.class.isAssignableFrom( attributeMetadata.getJavaType() ) ) {
return determineSimpleType( attributeMetadata.getMapKeyValueContext() );
}
if ( java.util.List.class.isAssignableFrom( attributeMetadata.getJavaType() ) ) {
}
return java.util.Map.class.isAssignableFrom( attributeMetadata.getJavaType() )
? determineSimpleType( attributeMetadata.getMapKeyValueContext() )
: null;
}
@SuppressWarnings("unchecked")
private <Y> SimpleDomainType<Y> determineSimpleType(ValueContext typeContext) {
final JavaTypeDescriptor<Y> javaTypeDescriptor = context.getSessionFactory()
.getMetamodel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( typeContext.getJpaBindableType() );
switch ( typeContext.getValueClassification() ) {
case BASIC: {
return new BasicTypeImpl<>( javaTypeDescriptor );
return context.resolveBasicType( typeContext.getJpaBindableType() );
}
case ENTITY: {
final org.hibernate.type.EntityType type = (EntityType) typeContext.getHibernateValue().getType();
@ -237,7 +246,7 @@ public class AttributeFactory {
javaType,
typeContext.getAttributeMetadata().getOwnerType(),
(ComponentType) typeContext.getHibernateValue().getType(),
context.getSessionFactory()
context.getSessionFactory().getQueryEngine().getCriteriaBuilder()
);
context.registerEmbeddableType( embeddableType );

View File

@ -33,6 +33,7 @@ import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
@ -41,8 +42,11 @@ import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.internal.AttributeContainer;
import org.hibernate.metamodel.model.domain.internal.BasicTypeImpl;
import org.hibernate.metamodel.model.domain.internal.EntityTypeImpl;
import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
/**
* Defines a context for storing information during the building of the {@link MetamodelImpl}.
@ -143,7 +147,7 @@ class MetadataContext {
}
/*package*/ void registerEmbeddableType(EmbeddableDomainType<?> embeddableType) {
if ( !( ignoreUnsupported && Map.class.isAssignableFrom( embeddableType.getJavaTypeDescriptor().getJavaType() ) ) ) {
if ( !( ignoreUnsupported && Map.class.isAssignableFrom( embeddableType.getExpressableJavaTypeDescriptor().getJavaType() ) ) ) {
embeddables.add( embeddableType );
}
}
@ -549,4 +553,19 @@ class MetadataContext {
public Set<MappedSuperclass> getUnusedMappedSuperclasses() {
return new HashSet<MappedSuperclass>( knownMappedSuperclasses );
}
private final Map<Class<?>,BasicDomainType<?>> basicDomainTypeMap = new HashMap<>();
public <J> BasicDomainType<J> resolveBasicType(Class<J> javaType) {
return basicDomainTypeMap.computeIfAbsent(
javaType,
jt -> {
final JavaTypeDescriptorRegistry registry = getSessionFactory()
.getMetamodel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry();
return new BasicTypeImpl<>( registry.resolveDescriptor( javaType ) );
}
)
}
}

View File

@ -30,12 +30,12 @@ public abstract class AbstractDomainType<J> implements DomainType<J> {
}
@Override
public JavaTypeDescriptor<J> getJavaTypeDescriptor() {
public JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor() {
return javaTypeDescriptor;
}
@Override
public Class<J> getJavaType() {
return getJavaTypeDescriptor().getJavaType();
return getExpressableJavaTypeDescriptor().getJavaType();
}
}

View File

@ -6,13 +6,12 @@
*/
package org.hibernate.metamodel.model.domain;
import org.hibernate.metamodel.CollectionClassification;
/**
* DomainType for a plural attribute
* Models Hibernate's ANY mapping (reverse discrimination) as a JPA domain model type
*
* @param <J> The base Java type defined for the any mapping
*
* @author Steve Ebersole
*/
public interface CollectionDomainType<C,E> extends DomainType<C> {
CollectionClassification getCollectionClassification();
public interface AnyMappingDomainType<J> extends SimpleDomainType<J> {
}

View File

@ -35,7 +35,7 @@ public interface DomainType<J> extends SqmExpressable<J> {
*/
default String getTypeName() {
// default impl to handle the general case returning the Java type name
return getJavaTypeDescriptor().getJavaType().getName();
return getExpressableJavaTypeDescriptor().getJavaType().getName();
}
/**
@ -44,5 +44,5 @@ public interface DomainType<J> extends SqmExpressable<J> {
*
* @see #getTypeName
*/
JavaTypeDescriptor<J> getJavaTypeDescriptor();
JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor();
}

View File

@ -9,10 +9,13 @@ package org.hibernate.metamodel.model.domain;
import java.util.List;
import javax.persistence.metamodel.ListAttribute;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Hibernate extension to the JPA {@link ListAttribute} descriptor
*
* @author Steve Ebersole
*/
public interface ListPersistentAttribute<D,E> extends ListAttribute<D,E>, PluralPersistentAttribute<D,List<E>,E> {
SqmPathSource<Integer> getIndexPathSource();
}

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.metamodel.model.domain;
import java.util.function.Consumer;
import javax.persistence.metamodel.ManagedType;
import org.hibernate.graph.spi.SubGraphImplementor;
@ -39,6 +40,9 @@ public interface ManagedDomainType<J> extends SimpleDomainType<J>, ManagedType<J
RepresentationMode getRepresentationMode();
void visitAttributes(Consumer<PersistentAttribute<? super J,?>> action);
void visitDeclaredAttributes(Consumer<PersistentAttribute<J,?>> action);
@Override
PersistentAttribute<? super J,?> getAttribute(String name);

View File

@ -9,12 +9,16 @@ package org.hibernate.metamodel.model.domain;
import java.util.Map;
import javax.persistence.metamodel.MapAttribute;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Hibernate extension to the JPA {@link MapAttribute} descriptor
*
* @author Steve Ebersole
*/
public interface MapPersistentAttribute<D,K,V> extends MapAttribute<D, K, V>, PluralPersistentAttribute<D,Map<K,V>,V> {
SqmPathSource getKeyPathSource();
@Override
SimpleDomainType<K> getKeyType();
}

View File

@ -8,25 +8,25 @@ package org.hibernate.metamodel.model.domain;
import javax.persistence.metamodel.Attribute;
import org.hibernate.metamodel.model.AttributeClassification;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.metamodel.AttributeClassification;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Hibernate extension to the JPA {@link Attribute} contract
*
* @author Steve Ebersole
*/
public interface PersistentAttribute<D,J> extends Attribute<D,J>, SqmPathSource<J> {
public interface PersistentAttribute<D,J> extends Attribute<D,J> {
@Override
ManagedDomainType<D> getDeclaringType();
JavaTypeDescriptor<J> getAttributeJavaTypeDescriptor();
/**
* The classification of the attribute (is it a basic type, entity, etc)
*/
AttributeClassification getAttributeClassification();
DomainType<?> getType();
SimpleDomainType<?> getValueGraphType();
SimpleDomainType<?> getKeyGraphType();
}

View File

@ -8,6 +8,10 @@ package org.hibernate.metamodel.model.domain;
import javax.persistence.metamodel.PluralAttribute;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Hibernate extension to the JPA {@link PluralAttribute} descriptor
*
@ -16,12 +20,14 @@ import javax.persistence.metamodel.PluralAttribute;
*
* @author Steve Ebersole
*/
public interface PluralPersistentAttribute<D,C,E> extends PluralAttribute<D,C,E>, PersistentAttribute<D,C> {
public interface PluralPersistentAttribute<D,C,E>
extends PersistentAttribute<D,C>, SqmPathSource<E>, SqmJoinable, PluralAttribute<D,C,E> {
@Override
ManagedDomainType<D> getDeclaringType();
@Override
CollectionDomainType<C,E> getType();
CollectionClassification getCollectionClassification();
SqmPathSource getElementPathSource();
@Override
SimpleDomainType<E> getElementType();

View File

@ -8,12 +8,16 @@ package org.hibernate.metamodel.model.domain;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Hibernate extension to the JPA {@link SingularAttribute} descriptor
*
* @author Steve Ebersole
*/
public interface SingularPersistentAttribute<D,J> extends SingularAttribute<D,J>, PersistentAttribute<D,J> {
public interface SingularPersistentAttribute<D,J>
extends SingularAttribute<D,J>, PersistentAttribute<D,J>, SqmPathSource<J>, SqmJoinable {
@Override
SimpleDomainType<J> getType();
@ -21,7 +25,7 @@ public interface SingularPersistentAttribute<D,J> extends SingularAttribute<D,J>
ManagedDomainType<D> getDeclaringType();
@Override
SimpleDomainType<J> getSqmNodeType();
SimpleDomainType<J> getSqmPathType();
/**
* For a singular attribute, the value type is defined as the

View File

@ -15,7 +15,7 @@ import java.lang.reflect.Method;
import javax.persistence.metamodel.Attribute;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.metamodel.model.AttributeClassification;
import org.hibernate.metamodel.AttributeClassification;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
@ -29,8 +29,7 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
*
* @author Steve Ebersole
*/
public abstract class AbstractAttribute<D,J,B>
implements PersistentAttribute<D,J>, Serializable {
public abstract class AbstractAttribute<D,J,B> implements PersistentAttribute<D,J>, Serializable {
private final ManagedDomainType<D> declaringType;
private final String name;
private final JavaTypeDescriptor<J> attributeType;
@ -72,13 +71,12 @@ public abstract class AbstractAttribute<D,J,B>
return attributeType.getJavaType();
}
@Override
public SimpleDomainType<B> getSqmNodeType() {
public SimpleDomainType<B> getSqmPathType() {
return valueType;
}
@Override
public JavaTypeDescriptor<J> getJavaTypeDescriptor() {
public JavaTypeDescriptor<J> getAttributeJavaTypeDescriptor() {
return attributeType;
}

View File

@ -10,10 +10,17 @@ import java.io.Serializable;
import java.util.Collection;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.ValueClassification;
import org.hibernate.metamodel.model.domain.AbstractManagedType;
import org.hibernate.metamodel.model.domain.CollectionDomainType;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
@ -29,18 +36,21 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
*/
public abstract class AbstractPluralAttribute<D,C,E>
extends AbstractAttribute<D,C,E>
implements PluralPersistentAttribute<D,C,E>, CollectionDomainType<C,E>, Serializable {
implements PluralPersistentAttribute<D,C,E>, Serializable {
public static <X,C,E,K> PluralAttributeBuilder<X,C,E,K> create(
AbstractManagedType<X> ownerType,
SimpleDomainType<E> attrType,
JavaTypeDescriptor<C> collectionClass,
SimpleDomainType<K> keyType) {
return new PluralAttributeBuilder<>( ownerType, attrType, collectionClass, keyType );
SimpleDomainType<K> keyType,
NodeBuilder nodeBuilder) {
return new PluralAttributeBuilder<>( ownerType, attrType, collectionClass, keyType, nodeBuilder );
}
private final CollectionClassification classification;
private final SqmPathSource<E> elementPathSource;
@SuppressWarnings("WeakerAccess")
protected AbstractPluralAttribute(PluralAttributeBuilder<D,C,E,?> builder) {
super(
builder.getDeclaringType(),
@ -52,6 +62,36 @@ public abstract class AbstractPluralAttribute<D,C,E>
);
this.classification = builder.getCollectionClassification();
this.elementPathSource = DomainModelHelper.resolveSqmPathSource(
interpretValueClassification( builder.getValueType() ),
getName(),
builder.getValueType(),
BindableType.PLURAL_ATTRIBUTE,
builder.getNodeBuilder()
);
}
private ValueClassification interpretValueClassification(SimpleDomainType<E> valueType) {
if ( valueType instanceof BasicDomainType ) {
return ValueClassification.BASIC;
}
if ( valueType instanceof AnyMappingDomainType ) {
return ValueClassification.ANY;
}
if ( valueType instanceof EmbeddableDomainType ) {
return ValueClassification.EMBEDDED;
}
if ( valueType instanceof EntityDomainType ) {
return ValueClassification.ENTITY;
}
throw new IllegalArgumentException(
"Unrecognized value type Java-type [" + valueType.getTypeName() + "] for plural attribute value"
);
}
@Override
@ -59,21 +99,24 @@ public abstract class AbstractPluralAttribute<D,C,E>
return classification;
}
@Override
public SqmPathSource<E> getElementPathSource() {
return elementPathSource;
}
@Override
public SqmPathSource<?> findSubPathSource(String name) {
return elementPathSource.findSubPathSource( name );
}
@Override
public CollectionType getCollectionType() {
return getCollectionClassification().toJpaClassification();
}
@Override
public CollectionDomainType<C, E> getType() {
return this;
}
@Override
public String getTypeName() {
// todo (6.0) : this should return the "role"
// - for now just return the name of the collection type
return getCollectionType().name();
public JavaTypeDescriptor<E> getExpressableJavaTypeDescriptor() {
return getElementType().getExpressableJavaTypeDescriptor();
}
@Override
@ -114,12 +157,14 @@ public abstract class AbstractPluralAttribute<D,C,E>
}
@Override
public Class<C> getJavaType() {
return getJavaTypeDescriptor().getJavaType();
}
@Override
public SqmPath<C> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
return new SqmPluralValuedSimplePath( );
public SqmPath<E> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
final NavigablePath navigablePath = lhs.getNavigablePath().append( getPathName() );
//noinspection unchecked
return new SqmPluralValuedSimplePath(
navigablePath,
this,
lhs,
creationState.getCreationContext().getNodeBuilder()
);
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.metamodel.model.domain.DomainType;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
*/
public abstract class AbstractSqmPathSource<J> implements SqmPathSource<J> {
private final String localPathName;
private final DomainType<J> domainType;
private final BindableType jpaBindableType;
private final NodeBuilder nodeBuilder;
public AbstractSqmPathSource(
String localPathName,
DomainType<J> domainType,
BindableType jpaBindableType,
NodeBuilder nodeBuilder) {
this.localPathName = localPathName;
this.domainType = domainType;
this.jpaBindableType = jpaBindableType;
this.nodeBuilder = nodeBuilder;
}
protected NodeBuilder getNodeBuilder() {
return nodeBuilder;
}
@Override
public String getPathName() {
return localPathName;
}
@Override
public DomainType<?> getSqmPathType() {
return domainType;
}
@Override
public BindableType getBindableType() {
return jpaBindableType;
}
@Override
public JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor() {
return domainType.getExpressableJavaTypeDescriptor();
}
@Override
public Class<J> getBindableJavaType() {
return getExpressableJavaTypeDescriptor().getJavaType();
}
}

View File

@ -1,70 +0,0 @@
/*
* 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 java.io.Serializable;
import javax.persistence.metamodel.Type;
import org.hibernate.metamodel.model.domain.spi.DomainTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Defines commonality for the JPA {@link Type} hierarchy of interfaces.
*
* @author Steve Ebersole
* @author Brad Koehn
*/
public abstract class AbstractType<X> implements DomainTypeDescriptor<X>, Serializable {
private final JavaTypeDescriptor<X> javaTypeDescriptor;
private final String typeName;
/**
* Instantiates the type based on the given Java type.
*/
protected AbstractType(JavaTypeDescriptor<X> javaTypeDescriptor) {
this(
javaTypeDescriptor,
javaTypeDescriptor.getJavaType() != null
? javaTypeDescriptor.getJavaType().getName()
: null
);
}
/**
* Instantiates the type based on the given Java type.
*/
protected AbstractType(JavaTypeDescriptor<X> javaTypeDescriptor, String typeName) {
this.javaTypeDescriptor = javaTypeDescriptor;
this.typeName = typeName == null ? "unknown" : typeName;
}
@Override
public JavaTypeDescriptor<X> getJavaTypeDescriptor() {
return javaTypeDescriptor;
}
/**
* {@inheritDoc}
*
* @implNote The Hibernate impl may return {@code null} here in the case of either
* dynamic models or entity classes mapped multiple times using entity-name. In
* these cases, the {@link #getTypeName()} value should be used.
*/
@Override
public Class<X> getJavaType() {
return javaTypeDescriptor.getJavaType();
}
/**
* Obtains the type name. See notes on {@link #getJavaType()} for details
*
* @return The type name
*/
public String getTypeName() {
return typeName;
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmPath;
/**
* @author Steve Ebersole
*/
public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
@SuppressWarnings("WeakerAccess")
public AnyMappingSqmPathSource(
String localPathName,
AnyMappingDomainType<J> domainType,
BindableType jpaBindableType,
NodeBuilder nodeBuilder) {
super( localPathName, domainType, jpaBindableType, nodeBuilder );
}
@Override
public AnyMappingDomainType<J> getSqmPathType() {
//noinspection unchecked
return (AnyMappingDomainType<J>) super.getSqmPathType();
}
@Override
public SqmPathSource<?> findSubPathSource(String name) {
throw new NotYetImplementedFor6Exception();
}
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
throw new NotYetImplementedFor6Exception();
}
}

View File

@ -21,7 +21,7 @@ public interface AttributeContainer<J> {
* Used during creation of the type
*/
interface InFlightAccess<J> {
void addAttribute(PersistentAttribute<J,?,?> attribute);
void addAttribute(PersistentAttribute<J,?> attribute);
default void applyIdAttribute(SingularPersistentAttribute<J, ?> idAttribute) {
throw new UnsupportedOperationException(

View File

@ -34,13 +34,4 @@ class BagAttributeImpl<X, E>
public SqmPathSource<?> findSubPathSource(String name) {
throw new NotYetImplementedFor6Exception();
}
@Override
public SemanticPathPart resolvePathPart(
String name,
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
throw new NotYetImplementedFor6Exception();
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.metamodel.model.domain.BasicDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
/**
* @author Steve Ebersole
*/
public class BasicSqmPathSource<J> extends AbstractSqmPathSource<J> {
@SuppressWarnings("WeakerAccess")
public BasicSqmPathSource(
String localPathName,
BasicDomainType<J> domainType,
BindableType jpaBindableType,
NodeBuilder nodeBuilder) {
super( localPathName, domainType, jpaBindableType, nodeBuilder );
}
@Override
public BasicDomainType<J> getSqmPathType() {
//noinspection unchecked
return (BasicDomainType<J>) super.getSqmPathType();
}
@Override
public SqmPathSource<?> findSubPathSource(String name) {
throw new IllegalArgumentException( "Basic paths cannot be dereferenced" );
}
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
final NavigablePath navigablePath = lhs.getNavigablePath().append( getPathName() );
return new SqmBasicValuedSimplePath<>(
navigablePath,
this,
lhs,
getNodeBuilder()
);
}
}

View File

@ -26,11 +26,11 @@ public class BasicTypeImpl<J> implements BasicDomainType<J>, Serializable {
}
@Override
public JavaTypeDescriptor<J> getJavaTypeDescriptor() {
public JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor() {
return javaTypeDescriptor;
}
public Class<J> getJavaType() {
return getJavaTypeDescriptor().getJavaType();
return getExpressableJavaTypeDescriptor().getJavaType();
}
}

View File

@ -6,13 +6,21 @@
*/
package org.hibernate.metamodel.model.domain.internal;
import javax.persistence.metamodel.Bindable;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.ValueClassification;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
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.ManagedDomainType;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
/**
* Helper containing utilities useful for domain model handling
@ -79,4 +87,48 @@ public class DomainModelHelper {
return sessionFactory.getMetamodel().entityPersister( hibernateEntityName );
}
public static <J> SqmPathSource<J> resolveSqmPathSource(
ValueClassification classification,
String name,
DomainType<J> valueDomainType,
Bindable.BindableType jpaBindableType,
NodeBuilder nodeBuilder) {
switch ( classification ) {
case BASIC: {
return new BasicSqmPathSource<>(
name,
(BasicDomainType<J>) valueDomainType,
jpaBindableType,
nodeBuilder
);
}
case ANY: {
return new AnyMappingSqmPathSource<>(
name,
(AnyMappingDomainType<J>) valueDomainType,
jpaBindableType,
nodeBuilder
);
}
case EMBEDDED: {
return new EmbeddedSqmPathSource<>(
name,
(EmbeddableDomainType<J>) valueDomainType,
jpaBindableType,
nodeBuilder
);
}
case ENTITY: {
return new EntitySqmPathSource<>(
name,
(EntityDomainType<J>) valueDomainType,
jpaBindableType,
nodeBuilder
);
}
default: {
throw new IllegalArgumentException( "Unrecognized ValueClassification : " + classification );
}
}
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
/**
* @author Steve Ebersole
*/
public class EmbeddedSqmPathSource<J> extends AbstractSqmPathSource<J> {
public EmbeddedSqmPathSource(
String localPathName,
EmbeddableDomainType<J> domainType,
BindableType jpaBindableType,
NodeBuilder nodeBuilder) {
super( localPathName, domainType, jpaBindableType, nodeBuilder );
}
@Override
public EmbeddableDomainType<J> getSqmPathType() {
//noinspection unchecked
return (EmbeddableDomainType<J>) super.getSqmPathType();
}
@Override
public SqmPathSource<?> findSubPathSource(String name) {
return (SqmPathSource<?>) getSqmPathType().findAttribute( name );
}
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
return new SqmAnyValuedSimplePath<>(
lhs.getNavigablePath().append( getPathName() ),
this,
lhs,
getNodeBuilder()
);
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
/**
* @author Steve Ebersole
*/
public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> {
public EntitySqmPathSource(
String localPathName,
EntityDomainType<J> domainType,
BindableType jpaBindableType,
NodeBuilder nodeBuilder) {
super( localPathName, domainType, jpaBindableType, nodeBuilder );
}
@Override
public EntityDomainType<J> getSqmPathType() {
//noinspection unchecked
return (EntityDomainType<J>) super.getSqmPathType();
}
@Override
public SqmPathSource<?> findSubPathSource(String name) {
return (SqmPathSource<?>) getSqmPathType().findAttribute( name );
}
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
return new SqmEntityValuedSimplePath<>(
lhs.getNavigablePath().append( getPathName() ),
this,
lhs,
getNodeBuilder()
);
}
}

View File

@ -68,7 +68,7 @@ public class EntityTypeImpl<J>
}
@Override
public DomainType<?> getSqmNodeType() {
public DomainType<?> getSqmPathType() {
return this;
}
@ -97,7 +97,7 @@ public class EntityTypeImpl<J>
}
@Override
public JavaTypeDescriptor<J> getJavaTypeDescriptor() {
public JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor() {
return null;
}

View File

@ -9,17 +9,45 @@ package org.hibernate.metamodel.model.domain.internal;
import java.util.List;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.SqmListJoin;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
/**
* @author Steve Ebersole
*/
class ListAttributeImpl<X, E> extends AbstractPluralAttribute<X, List<E>, E> implements ListPersistentAttribute<X, E> {
private final SqmPathSource<Integer> indexPathSource;
ListAttributeImpl(PluralAttributeBuilder<X, List<E>, E, ?> xceBuilder) {
super( xceBuilder );
indexPathSource =
}
@Override
public CollectionType getCollectionType() {
return CollectionType.LIST;
}
@Override
public SqmAttributeJoin createSqmJoin(
SqmFrom lhs,
SqmJoinType joinType,
String alias,
boolean fetched,
SqmCreationState creationState) {
//noinspection unchecked
return new SqmListJoin(
lhs,
this,
alias,
joinType,
fetched,
creationState.getCreationContext().getNodeBuilder()
);
}
}

View File

@ -14,9 +14,10 @@ import java.util.Set;
import org.hibernate.mapping.Property;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.model.AttributeClassification;
import org.hibernate.metamodel.AttributeClassification;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
@ -26,6 +27,8 @@ public class PluralAttributeBuilder<D, C, E, K> {
private final ManagedDomainType<D> declaringType;
private final SimpleDomainType<E> valueType;
private final NodeBuilder nodeBuilder;
private SimpleDomainType<K> keyType;
private AttributeClassification attributeClassification;
@ -39,11 +42,17 @@ public class PluralAttributeBuilder<D, C, E, K> {
ManagedDomainType<D> ownerType,
SimpleDomainType<E> elementType,
JavaTypeDescriptor<C> collectionJavaTypeDescriptor,
SimpleDomainType<K> keyType) {
SimpleDomainType<K> keyType,
NodeBuilder nodeBuilder) {
this.declaringType = ownerType;
this.valueType = elementType;
this.collectionJavaTypeDescriptor = collectionJavaTypeDescriptor;
this.keyType = keyType;
this.nodeBuilder = nodeBuilder;
}
public NodeBuilder getNodeBuilder() {
return nodeBuilder;
}
public ManagedDomainType<D> getDeclaringType() {

View File

@ -8,23 +8,23 @@ package org.hibernate.metamodel.model.domain.internal;
import java.io.Serializable;
import java.lang.reflect.Member;
import java.util.Locale;
import java.util.function.Supplier;
import org.hibernate.graph.spi.GraphHelper;
import org.hibernate.metamodel.model.AttributeClassification;
import org.hibernate.metamodel.AttributeClassification;
import org.hibernate.metamodel.ValueClassification;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath;
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.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.domain.SqmSingularJoin;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Emmanuel Bernard
@ -37,7 +37,7 @@ public class SingularAttributeImpl<D,J>
private final boolean isVersion;
private final boolean isOptional;
private final SimpleDomainType<J> attributeType;
private final SqmPathSource<J> sqmPathSource;
// NOTE : delay access for timing reasons
private final DelayedKeyTypeAccess graphKeyTypeAccess = new DelayedKeyTypeAccess();
@ -50,18 +50,55 @@ public class SingularAttributeImpl<D,J>
Member member,
boolean isIdentifier,
boolean isVersion,
boolean isOptional) {
super( declaringType, name, attributeType.getJavaTypeDescriptor(), attributeClassification, attributeType, member );
boolean isOptional,
NodeBuilder nodeBuilder) {
super( declaringType, name, attributeType.getExpressableJavaTypeDescriptor(), attributeClassification, attributeType, member );
this.isIdentifier = isIdentifier;
this.isVersion = isVersion;
this.isOptional = isOptional;
this.attributeType = attributeType;
this.sqmPathSource = DomainModelHelper.resolveSqmPathSource(
determineValueClassification( attributeClassification ),
name,
attributeType,
BindableType.SINGULAR_ATTRIBUTE,
nodeBuilder
);
}
private static ValueClassification determineValueClassification(AttributeClassification attributeClassification) {
switch ( attributeClassification ) {
case BASIC: {
return ValueClassification.BASIC;
}
case ANY: {
return ValueClassification.ANY;
}
case EMBEDDED: {
return ValueClassification.EMBEDDED;
}
case ONE_TO_ONE:
case MANY_TO_ONE: {
return ValueClassification.ENTITY;
}
default: {
throw new IllegalArgumentException(
"Unrecognized AttributeClassification (for singular attribute): " + attributeClassification
);
}
}
}
@Override
public SimpleDomainType<J> getSqmPathType() {
//noinspection unchecked
return (SimpleDomainType<J>) sqmPathSource.getSqmPathType();
}
@Override
public SimpleDomainType<J> getValueGraphType() {
return attributeType;
return getSqmPathType();
}
@Override
@ -70,43 +107,42 @@ public class SingularAttributeImpl<D,J>
}
@Override
public SimpleDomainType<J> getSqmNodeType() {
return super.getSqmNodeType();
public SimpleDomainType<J> getType() {
return getSqmPathType();
}
public JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor() {
return sqmPathSource.getExpressableJavaTypeDescriptor();
}
@Override
public Class<J> getBindableJavaType() {
return getExpressableJavaTypeDescriptor().getJavaType();
}
@Override
public SqmPathSource<?> findSubPathSource(String name) {
switch ( getAttributeClassification() ) {
case EMBEDDED:
case ONE_TO_ONE:
case MANY_TO_ONE: {
return ( (SqmPathSource) getSqmNodeType() ).findSubPathSource( name );
}
default: {
throw new UnsupportedOperationException( "Attribute does not contain sub-paths" );
}
}
return sqmPathSource.findSubPathSource( name );
}
@Override
public SemanticPathPart resolvePathPart(
String name,
String currentContextKey,
boolean isTerminal,
public SqmAttributeJoin<D,J> createSqmJoin(
SqmFrom lhs,
SqmJoinType joinType,
String alias,
boolean fetched,
SqmCreationState creationState) {
return findSubPathSource( name );
//noinspection unchecked
return new SqmSingularJoin(
lhs,
this,
alias,
joinType,
fetched,
creationState.getCreationContext().getNodeBuilder()
);
}
@Override
public SqmPath resolveIndexedAccess(
SqmExpression selector,
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
throw new UnsupportedOperationException( "Singular attribute cannot be index-accessed" );
}
/**
* Subclass used to simplify instantiation of singular attributes representing an entity's
* identifier.
@ -117,8 +153,19 @@ public class SingularAttributeImpl<D,J>
String name,
SimpleDomainType<J> attributeType,
Member member,
AttributeClassification attributeClassification) {
super( declaringType, name, attributeClassification, attributeType, member, true, false, false );
AttributeClassification attributeClassification,
NodeBuilder nodeBuilder) {
super(
declaringType,
name,
attributeClassification,
attributeType,
member,
true,
false,
false,
nodeBuilder
);
}
}
@ -132,8 +179,19 @@ public class SingularAttributeImpl<D,J>
String name,
AttributeClassification attributeClassification,
SimpleDomainType<Y> attributeType,
Member member) {
super( declaringType, name, attributeClassification, attributeType, member, false, true, false );
Member member,
NodeBuilder nodeBuilder) {
super(
declaringType,
name,
attributeClassification,
attributeType,
member,
false,
true,
false,
nodeBuilder
);
}
}
@ -152,11 +210,6 @@ public class SingularAttributeImpl<D,J>
return isOptional;
}
@Override
public SimpleDomainType<J> getType() {
return attributeType;
}
@Override
public boolean isAssociation() {
return getPersistentAttributeType() == PersistentAttributeType.MANY_TO_ONE
@ -174,40 +227,10 @@ public class SingularAttributeImpl<D,J>
}
@Override
public Class<J> getBindableJavaType() {
return attributeType.getJavaType();
}
@Override
public SqmPath createSqmPath(
public SqmPath<J> createSqmPath(
SqmPath lhs,
SqmCreationState creationState) {
switch ( getAttributeClassification() ) {
case BASIC: {
return new SqmBasicValuedSimplePath( );
}
case EMBEDDED: {
return new SqmEmbeddedValuedSimplePath( );
}
case ANY: {
return new SqmAnyValuedSimplePath( );
}
case ONE_TO_ONE:
case MANY_TO_ONE: {
return new SqmEntityValuedSimplePath( );
}
default: {
throw new UnsupportedOperationException(
String.format(
Locale.ROOT,
"Cannot create SqmPath from singular attribute [%s#%s] - unknown classification : %s",
getDeclaringType().getTypeName(),
getName(),
getAttributeClassification()
)
);
}
}
return sqmPathSource.createSqmPath( lhs, creationState );
}
private class DelayedKeyTypeAccess implements Supplier<SimpleDomainType<J>>, Serializable {

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.persister.entity;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.QueryException;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.persister.SqlExpressableType;
@ -33,29 +34,19 @@ import org.hibernate.type.Type;
* @author Steve Ebersole
*/
public interface PropertyMapping {
/**
* Get the type of the thing containing the properties
*
* todo (6.0) : this really should be defined in terms of the Hibernate mapping model, not (just?) the JPA model
* - meaning maybe it exposes both
*/
DomainType getDomainType();
SqlExpressableType getMappingType();
//
/**
* @asciidoc
*
* Resolve a sub-reference relative to this PropertyMapping. E.g.,
* @asciidoc Resolve a sub-reference relative to this PropertyMapping. E.g.,
* given the PropertyMapping for an entity named `Person` with an embedded
* property `#name` calling this method with `"name"` returns the
* PropertyMapping for the `Name` embeddable
*
* <p>
* todo (6.0) : define an exception in the signature for cases where the PropertyMapping
* cannot be de-referenced (basic values)
* cannot be de-referenced (basic values)
*/
PropertyMapping resolveSubMapping(String name);
default PropertyMapping resolveSubMapping(String name) {
throw new NotYetImplementedFor6Exception();
}
// todo (6.0) : add capability to create SqmPath, i.e.
// SqmPath createSqmPath(SqmPath<?> lhs, SqmCreationState creationState);

View File

@ -15,5 +15,5 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
* @author Steve Ebersole
*/
public interface SqmExpressable<J> {
JavaTypeDescriptor<J> getJavaTypeDescriptor();
JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor();
}

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.query.sqm;
import org.hibernate.metamodel.model.domain.spi.PersistentAttributeDescriptor;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
@ -20,7 +19,7 @@ import org.hibernate.query.sqm.tree.from.SqmFrom;
*
* @author Steve Ebersole
*/
public interface SqmJoinable<O,T,B> extends PersistentAttributeDescriptor<O,T,B> {
public interface SqmJoinable {
SqmAttributeJoin createSqmJoin(
SqmFrom lhs,
SqmJoinType joinType,

View File

@ -6,11 +6,11 @@
*/
package org.hibernate.query.sqm;
import javax.persistence.metamodel.Bindable;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
/**
* Represents parts of the application's domain model that can be used
@ -21,7 +21,7 @@ import org.hibernate.query.sqm.tree.expression.SqmExpression;
*
* @author Steve Ebersole
*/
public interface SqmPathSource<J> extends SqmExpressable<J>, SemanticPathPart {
public interface SqmPathSource<J> extends SqmExpressable<J>, Bindable<J> {
/**
* The name of this thing. Mainly used in logging and when creating a
* {@link org.hibernate.query.NavigablePath}
@ -29,9 +29,10 @@ public interface SqmPathSource<J> extends SqmExpressable<J>, SemanticPathPart {
String getPathName();
/**
* The type of SqmPaths this source creates
* The type of SqmPaths this source creates. Corollary to JPA's
* {@link Bindable#getBindableJavaType()}
*/
DomainType<?> getSqmNodeType();
DomainType<?> getSqmPathType();
SqmPathSource<?> findSubPathSource(String name);
@ -39,13 +40,4 @@ public interface SqmPathSource<J> extends SqmExpressable<J>, SemanticPathPart {
* Create an SQM path for this source relative to the given left-hand side
*/
SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState);
@Override
default SqmPath resolveIndexedAccess(
SqmExpression selector,
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
throw new UnsupportedOperationException( "SqmPathSource [" + getClass().getName() + "] cannot be index accessed" );
}
}

View File

@ -16,13 +16,12 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
* @author Steve Ebersole
*/
public interface SqmTypedNode<T> extends SqmNode {
/**
* The Java type descriptor for this node.
*/
default JavaTypeDescriptor<T> getJavaTypeDescriptor() {
default JavaTypeDescriptor<T> getNodeJavaTypeDescriptor() {
final SqmExpressable<T> nodeType = getNodeType();
return nodeType != null ? nodeType.getJavaTypeDescriptor() : null;
return nodeType != null ? nodeType.getExpressableJavaTypeDescriptor() : null;
}
SqmExpressable<T> getNodeType();

View File

@ -11,7 +11,6 @@ import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.mapping.spi.Navigable;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.sqm.NodeBuilder;
@ -24,8 +23,7 @@ import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.sql.ast.produce.metamodel.spi.Joinable;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.jboss.logging.Logger;
@ -44,16 +42,18 @@ public abstract class AbstractSqmAttributeJoin<O,T>
private SqmPredicate onClausePredicate;
@SuppressWarnings("WeakerAccess")
public AbstractSqmAttributeJoin(
SqmFrom<?,O> lhs,
SqmJoinable<O,T,?> joinedNavigable,
SqmJoinable<O,T> joinedNavigable,
String alias,
SqmJoinType joinType,
boolean fetched,
NodeBuilder nodeBuilder) {
//noinspection unchecked
super(
SqmCreationHelper.buildSubNavigablePath( lhs, joinedNavigable, alias ),
joinedNavigable,
SqmCreationHelper.buildSubNavigablePath( lhs, joinedNavigable.getName(), alias ),
(SqmPathSource<O>) joinedNavigable,
lhs,
alias,
joinType,
@ -69,13 +69,8 @@ public abstract class AbstractSqmAttributeJoin<O,T>
}
@Override
public SqmJoinable getReferencedPathSource() {
return (SqmJoinable) super.getReferencedPathSource();
}
@Override
public JavaTypeDescriptor<T> getJavaTypeDescriptor() {
return getReferencedPathSource().getJavaTypeDescriptor();
public JavaTypeDescriptor<T> getNodeJavaTypeDescriptor() {
return getJavaTypeDescriptor();
}
public boolean isFetched() {
@ -113,7 +108,7 @@ public abstract class AbstractSqmAttributeJoin<O,T>
@Override
public void prepareForSubNavigableReference(
Navigable subNavigable,
SqmPathSource subNavigable,
boolean isSubReferenceTerminal,
SqmCreationState creationState) {
// nothing to prepare
@ -125,7 +120,8 @@ public abstract class AbstractSqmAttributeJoin<O,T>
@Override
public PersistentAttribute<? super O, ?> getAttribute() {
return getReferencedPathSource();
//noinspection unchecked
return (PersistentAttribute<? super O, ?>) getReferencedPathSource();
}
@Override

View File

@ -6,9 +6,7 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.spi.NavigableContainer;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.from.SqmFrom;
/**
@ -46,11 +44,4 @@ public abstract class AbstractSqmCorrelatedFrom<O,T>
public boolean isCorrelated() {
return true;
}
@Override
public SqmPathSource<?, T> getReferencedPathSource() {
return correlationParent.getReferencedPathSource();
}
}

View File

@ -26,8 +26,8 @@ import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.domain.BagPersistentAttribute;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.spi.EntityTypeDescriptor;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SetPersistentAttribute;
@ -37,7 +37,6 @@ import org.hibernate.query.criteria.JpaPath;
import org.hibernate.query.criteria.JpaSubQuery;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
@ -113,7 +112,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
return creationState.getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
subNavPath,
snp -> {
final SqmPathSource subSource = getReferencedPathSource().findSubPathSource( name );
final SqmPathSource<?> subSource = getReferencedPathSource().findSubPathSource( name );
if ( subSource == null ) {
throw UnknownPathException.unknownSubPath( this, name );
}
@ -249,7 +248,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
@Override
@SuppressWarnings("unchecked")
public SqmAttributeJoin join(String attributeName, JoinType jt) {
final SqmPathSource<?,?> subPathSource = getReferencedPathSource().findSubPathSource( attributeName );
final SqmPathSource<?> subPathSource = getReferencedPathSource().findSubPathSource( attributeName );
return buildJoin( subPathSource, SqmJoinType.from( jt ), false );
}
@ -263,7 +262,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
@Override
@SuppressWarnings("unchecked")
public SqmBagJoin joinCollection(String attributeName, JoinType jt) {
final SqmPathSource<?,?> joinedPathSource = getReferencedPathSource().findSubPathSource( attributeName );
final SqmPathSource<?> joinedPathSource = getReferencedPathSource().findSubPathSource( attributeName );
if ( joinedPathSource instanceof BagPersistentAttribute ) {
return buildBagJoin( (BagPersistentAttribute) joinedPathSource, SqmJoinType.from( jt ), false );
@ -289,7 +288,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
@Override
@SuppressWarnings("unchecked")
public SqmSetJoin joinSet(String attributeName, JoinType jt) {
final SqmPathSource<?,?> joinedPathSource = getReferencedPathSource().findSubPathSource( attributeName );
final SqmPathSource<?> joinedPathSource = getReferencedPathSource().findSubPathSource( attributeName );
if ( joinedPathSource instanceof SetPersistentAttribute ) {
return buildSetJoin( (SetPersistentAttribute) joinedPathSource, SqmJoinType.from( jt ), false );
@ -315,7 +314,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
@Override
@SuppressWarnings("unchecked")
public SqmListJoin joinList(String attributeName, JoinType jt) {
final SqmPathSource<?,?> joinedPathSource = getReferencedPathSource().findSubPathSource( attributeName );
final SqmPathSource<?> joinedPathSource = getReferencedPathSource().findSubPathSource( attributeName );
if ( joinedPathSource instanceof ListPersistentAttribute ) {
return buildListJoin( (ListPersistentAttribute) joinedPathSource, SqmJoinType.from( jt ), false );
@ -341,7 +340,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
@Override
@SuppressWarnings("unchecked")
public SqmMapJoin joinMap(String attributeName, JoinType jt) {
final SqmPathSource<?,?> joinedPathSource = getReferencedPathSource().findSubPathSource( attributeName );
final SqmPathSource<?> joinedPathSource = getReferencedPathSource().findSubPathSource( attributeName );
if ( joinedPathSource instanceof MapPersistentAttribute ) {
return buildMapJoin( (MapPersistentAttribute) joinedPathSource, SqmJoinType.from( jt ), false );
@ -404,12 +403,12 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
@Override
@SuppressWarnings("unchecked")
public <X,A> SqmAttributeJoin<X,A> fetch(String attributeName, JoinType jt) {
final SqmPathSource<?,?> fetchedPathSource = getReferencedPathSource().findSubPathSource( attributeName );
final SqmPathSource<?> fetchedPathSource = getReferencedPathSource().findSubPathSource( attributeName );
return buildJoin( fetchedPathSource, SqmJoinType.from( jt ), true );
}
private <A> SqmAttributeJoin buildJoin(
SqmPathSource<?,A> joinedPathSource,
SqmPathSource<A> joinedPathSource,
SqmJoinType joinType,
boolean fetched) {
if ( joinedPathSource instanceof SingularPersistentAttribute ) {
@ -463,21 +462,22 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
);
}
@SuppressWarnings("unchecked")
private <A> SqmSingularJoin<T,A> buildSingularJoin(
SingularPersistentAttribute<T,A> attribute,
SqmJoinType joinType,
boolean fetched) {
if ( attribute instanceof SqmJoinable ) {
return new SqmSingularJoin<>(
if ( attribute.getSqmPathType() instanceof ManagedDomainType ) {
//noinspection unchecked
return new SqmSingularJoin(
this,
(SqmJoinable<T,A,A>) attribute,
attribute,
null,
joinType,
fetched,
nodeBuilder()
);
}
throw new SemanticException( "Attribute [" + attribute + "] is not joinable" );
}

View File

@ -21,7 +21,7 @@ public abstract class AbstractSqmJoin<O,T> extends AbstractSqmFrom<O,T> implemen
public AbstractSqmJoin(
NavigablePath navigablePath,
SqmPathSource<O,T> referencedNavigable,
SqmPathSource<T> referencedNavigable,
SqmFrom lhs,
String alias,
SqmJoinType joinType,

View File

@ -10,7 +10,6 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.BiFunction;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
@ -23,8 +22,11 @@ import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
@ -38,7 +40,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
@SuppressWarnings("WeakerAccess")
protected AbstractSqmPath(
NavigablePath navigablePath,
SqmPathSource<?> referencedPathSource,
SqmPathSource<T> referencedPathSource,
SqmPath<?> lhs,
NodeBuilder nodeBuilder) {
super( referencedPathSource, nodeBuilder );
@ -46,8 +48,18 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
this.lhs = lhs;
}
@Override
public SqmPathSource<T> getNodeType() {
return (SqmPathSource<T>) super.getNodeType();
}
@Override
public SqmPathSource<T> getReferencedPathSource() {
return (SqmPathSource<T>) super.getNodeType();
}
@SuppressWarnings("WeakerAccess")
protected AbstractSqmPath(SqmPathSource<?> referencedPathSource, SqmPath lhs, NodeBuilder nodeBuilder) {
protected AbstractSqmPath(SqmPathSource<T> referencedPathSource, SqmPath lhs, NodeBuilder nodeBuilder) {
this(
lhs == null
? new NavigablePath( referencedPathSource.getPathName() )
@ -79,9 +91,8 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
}
@Override
@SuppressWarnings("unchecked")
public Bindable<T> getModel() {
return (Bindable<T>) getReferencedPathSource();
public SqmPathSource<T> getModel() {
return getReferencedPathSource();
}
private SqmExpression pathTypeExpression;
@ -90,19 +101,70 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
@SuppressWarnings("unchecked")
public SqmExpression<Class<? extends T>> type() {
if ( pathTypeExpression == null ) {
final DomainType sqmNodeType = getReferencedPathSource().getSqmNodeType();
final String discriminatorPathName = "{type}";
final NavigablePath discriminatorNavigablePath = getNavigablePath().append( discriminatorPathName );
final DomainType sqmNodeType = getReferencedPathSource().getSqmPathType();
if ( sqmNodeType instanceof EntityDomainType ) {
final SqmPathSource discriminatorPathSource = new SqmPathSource() {
@Override
public String getPathName() {
return discriminatorPathName;
}
@Override
public DomainType<?> getSqmPathType() {
return null;
}
@Override
public SqmPathSource<?> findSubPathSource(String name) {
throw new UnsupportedOperationException( "Entity discriminator cannot be de-referenced" );
}
@Override
public SqmPath createSqmPath(SqmPath lhs, SqmCreationState creationState) {
return new SqmBasicValuedSimplePath( discriminatorNavigablePath, this, AbstractSqmPath.this, nodeBuilder() );
}
@Override
public BindableType getBindableType() {
return BindableType.SINGULAR_ATTRIBUTE;
}
@Override
public Class getBindableJavaType() {
return null;
}
@Override
public JavaTypeDescriptor getExpressableJavaTypeDescriptor() {
return null;
}
@Override
public SemanticPathPart resolvePathPart(
String name,
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
return findSubPathSource( name );
}
};
pathTypeExpression = new SqmBasicValuedSimplePath(
getNavigablePath().append( "{type}" ),
???,
discriminatorNavigablePath,
discriminatorPathSource,
this,
nodeBuilder()
);
}
else {
throw new ...
// todo (6.0) : not sure this is strictly true
throw new UnsupportedOperationException( "SqmPath [" + getClass().getName() + "] cannot be typed" );
}
}
return pathTypeExpression;
}
@ -121,39 +183,40 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
final SqmPathSource subNavigable = getReferencedPathSource().findSubPathSource( attributeName );
if ( subNavigable instanceof SingularPersistentAttribute ) {
return createSingularPath( pathSource, (SingularPersistentAttribute) subNavigable );
return createSingularPath( (SingularPersistentAttribute) subNavigable );
}
else {
assert subNavigable instanceof PluralPersistentAttribute;
return createPluralPath( pathSource, (PluralPersistentAttribute) subNavigable );
return createPluralPath( (PluralPersistentAttribute) subNavigable );
}
}
);
}
private SqmPath createSingularPath(SqmPath lhs, SingularPersistentAttribute attribute) {
@SuppressWarnings("unchecked")
private SqmPath createSingularPath(SingularPersistentAttribute attribute) {
final NavigablePath subNavPath = getNavigablePath().append( attribute.getPathName() );
switch ( attribute.getAttributeClassification() ) {
case BASIC: {
return new SqmBasicValuedSimplePath( subNavPath, );
return new SqmBasicValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
}
case EMBEDDED: {
return new SqmEmbeddedValuedSimplePath( subNavPath, );
return new SqmEmbeddedValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
}
case ANY: {
return new SqmAnyValuedSimplePath( subNavPath, );
return new SqmAnyValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
}
case ONE_TO_ONE:
case MANY_TO_ONE: {
return new SqmEntityValuedSimplePath( subNavPath, );
return new SqmEntityValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
}
default: {
throw new UnsupportedOperationException(
String.format(
Locale.ROOT,
"Cannot create SqmPath from singular attribute [%s#%s] - unknown classification : %s",
attribute.getDeclaringType().getName(),
attribute.getDeclaringType().getTypeName(),
attribute.getName(),
attribute.getAttributeClassification()
)
@ -162,11 +225,12 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
}
}
private SqmPath createPluralPath(
SqmPath lhs,
PluralPersistentAttribute pluralAttribute) {
private SqmPath createPluralPath(PluralPersistentAttribute pluralAttribute) {
return new SqmPluralValuedSimplePath(
getNavigablePath().append( pluralAttribute.getPathName(),
getNavigablePath().append( pluralAttribute.getPathName() ),
pluralAttribute,
this,
nodeBuilder()
);
}
@ -194,7 +258,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
final SingularPersistentAttribute attribute = (SingularPersistentAttribute) jpaAttribute;
return resolvePath(
attribute.getName(),
(pathSource, name) -> createSingularPath( pathSource, attribute )
(pathSource, name) -> createSingularPath( attribute )
);
}
@ -203,7 +267,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
public SqmPath get(PluralAttribute attribute) {
return resolvePath(
attribute.getName(),
(pathSource, name) -> createPluralPath( pathSource, (PluralPersistentAttribute) attribute )
(pathSource, name) -> createPluralPath( (PluralPersistentAttribute) attribute )
);
}
@ -212,7 +276,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
public SqmPath get(MapAttribute map) {
return resolvePath(
map.getName(),
(pathSource, name) -> createPluralPath( pathSource, (MapPersistentAttribute) map )
(pathSource, name) -> createPluralPath( (MapPersistentAttribute) map )
);
}
}

View File

@ -8,19 +8,19 @@ package org.hibernate.query.sqm.tree.domain;
import javax.persistence.criteria.PluralJoin;
import org.hibernate.metamodel.model.mapping.spi.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.criteria.JpaJoin;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.sql.ast.produce.metamodel.spi.Joinable;
/**
* @author Steve Ebersole
*/
public abstract class AbstractSqmPluralJoin<O,C,E> extends AbstractSqmAttributeJoin<O,E> implements JpaJoin<O,E>, PluralJoin<O,C,E> {
@SuppressWarnings("WeakerAccess")
public AbstractSqmPluralJoin(
SqmFrom<?, O> lhs,
PluralPersistentAttribute<O,C,E> joinedNavigable,
@ -28,9 +28,10 @@ public abstract class AbstractSqmPluralJoin<O,C,E> extends AbstractSqmAttributeJ
SqmJoinType joinType,
boolean fetched,
NodeBuilder nodeBuilder) {
//noinspection unchecked
super(
lhs,
(Joinable<O, E>) joinedNavigable,
(SqmJoinable<O, E>) joinedNavigable,
alias,
joinType,
fetched,
@ -39,8 +40,8 @@ public abstract class AbstractSqmPluralJoin<O,C,E> extends AbstractSqmAttributeJ
}
@Override
public SqmPathSource<?, E> getReferencedPathSource() {
return (PluralPersistentAttribute) super.getReferencedPathSource();
public PluralPersistentAttribute<O,C,E> getReferencedPathSource() {
return (PluralPersistentAttribute<O, C, E>) super.getReferencedPathSource();
}
@Override

View File

@ -16,6 +16,7 @@ import org.hibernate.query.sqm.SqmPathSource;
public abstract class AbstractSqmSimplePath<T> extends AbstractSqmPath<T> implements SqmNavigableReference<T> {
private final NavigablePath navigablePath;
@SuppressWarnings("WeakerAccess")
public AbstractSqmSimplePath(
NavigablePath navigablePath,
SqmPathSource<T> referencedPathSource,
@ -24,6 +25,7 @@ public abstract class AbstractSqmSimplePath<T> extends AbstractSqmPath<T> implem
this( navigablePath, referencedPathSource, lhs, null, nodeBuilder );
}
@SuppressWarnings("WeakerAccess")
public AbstractSqmSimplePath(
NavigablePath navigablePath,
SqmPathSource<T> referencedPathSource,

View File

@ -7,9 +7,8 @@
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.mapping.spi.EntityValuedNavigable;
import org.hibernate.metamodel.model.mapping.spi.Navigable;
import org.hibernate.metamodel.model.mapping.PersistentCollectionDescriptor;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
@ -19,33 +18,34 @@ import org.hibernate.query.criteria.PathException;
public abstract class AbstractSqmSpecificPluralPartPath<T> extends AbstractSqmPath<T> implements SqmPath<T> {
private final NavigablePath navigablePath;
private final SqmPath pluralDomainPath;
private final PersistentCollectionDescriptor<?,?,T> collectionDescriptor;
private final PluralPersistentAttribute<?,?,T> pluralAttribute;
private String alias;
@SuppressWarnings("WeakerAccess")
public AbstractSqmSpecificPluralPartPath(
NavigablePath navigablePath,
SqmPath<?> pluralDomainPath,
Navigable<T> referencedNavigable) {
PluralPersistentAttribute<?,?,T> referencedAttribute) {
super(
navigablePath,
referencedNavigable,
referencedAttribute,
pluralDomainPath,
pluralDomainPath.nodeBuilder()
);
this.navigablePath = navigablePath;
this.pluralDomainPath = pluralDomainPath;
//noinspection unchecked
this.collectionDescriptor = pluralDomainPath.sqmAs( PersistentCollectionDescriptor.class );
this.pluralAttribute = referencedAttribute;
}
@SuppressWarnings("WeakerAccess")
public SqmPath getPluralDomainPath() {
return pluralDomainPath;
}
public PersistentCollectionDescriptor<?,?,T> getCollectionDescriptor() {
return collectionDescriptor;
@SuppressWarnings("WeakerAccess")
public PluralPersistentAttribute<?,?,T> getPluralAttribute() {
return pluralAttribute;
}
@Override
@ -70,7 +70,7 @@ public abstract class AbstractSqmSpecificPluralPartPath<T> extends AbstractSqmPa
@Override
public <S extends T> SqmTreatedPath<T, S> treatAs(Class<S> treatJavaType) throws PathException {
if ( getReferencedPathSource() instanceof EntityValuedNavigable ) {
if ( getReferencedPathSource().getSqmPathType() instanceof EntityDomainType ) {
throw new NotYetImplementedFor6Exception();
}

View File

@ -6,10 +6,12 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
@ -18,33 +20,40 @@ import org.hibernate.query.sqm.produce.spi.SqmCreationState;
* @author Steve Ebersole
*/
public class SqmAnyValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
@SuppressWarnings("WeakerAccess")
public SqmAnyValuedSimplePath(
NavigablePath navigablePath,
Navigable<T> referencedNavigable,
SqmPath lhs, NodeBuilder nodeBuilder) {
super( navigablePath, referencedNavigable, lhs, nodeBuilder );
SqmPathSource<T> referencedPathSource,
SqmPath lhs,
NodeBuilder nodeBuilder) {
super( navigablePath, referencedPathSource, lhs, nodeBuilder );
assert referencedPathSource.getSqmPathType() instanceof AnyMappingDomainType;
}
@SuppressWarnings("unused")
public SqmAnyValuedSimplePath(
NavigablePath navigablePath,
Navigable<T> referencedNavigable,
SqmPath lhs, String explicitAlias, NodeBuilder nodeBuilder) {
super( navigablePath, referencedNavigable, lhs, explicitAlias, nodeBuilder );
}
SqmPathSource<T> referencedPathSource,
SqmPath lhs,
String explicitAlias,
NodeBuilder nodeBuilder) {
super( navigablePath, referencedPathSource, lhs, explicitAlias, nodeBuilder );
@Override
public PropertyMapping getReferencedPropertyMapping() {
return null;
assert referencedPathSource.getSqmPathType() instanceof AnyMappingDomainType;
}
@Override
public <S extends T> SqmTreatedPath<T, S> treatAs(Class<S> treatJavaType) throws PathException {
return null;
throw new NotYetImplementedFor6Exception();
}
@Override
public SemanticPathPart resolvePathPart(
String name, String currentContextKey, boolean isTerminal, SqmCreationState creationState) {
String name,
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
return null;
}

View File

@ -14,22 +14,23 @@ import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.mapping.spi.BagPersistentAttribute;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.domain.BagPersistentAttribute;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.JpaCollectionJoin;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.criteria.JpaSubQuery;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
*/
public class SqmBagJoin<O, E> extends AbstractSqmPluralJoin<O,Collection<E>, E> implements JpaCollectionJoin<O, E> {
@SuppressWarnings("WeakerAccess")
public SqmBagJoin(
SqmFrom<?,O> lhs,
BagPersistentAttribute<O,E> attribute,
@ -41,18 +42,19 @@ public class SqmBagJoin<O, E> extends AbstractSqmPluralJoin<O,Collection<E>, E>
}
@Override
public SqmPathSource<?, E> getReferencedPathSource() {
return (BagPersistentAttribute) super.getReferencedPathSource();
public JavaTypeDescriptor<E> getJavaTypeDescriptor() {
return getModel().getExpressableJavaTypeDescriptor();
}
@Override
public BagPersistentAttribute<O,E> getModel() {
return getReferencedPathSource();
return (BagPersistentAttribute<O, E>) getReferencedPathSource();
}
@Override
public BagPersistentAttribute<O,E> getAttribute() {
return getReferencedPathSource();
//noinspection unchecked
return (BagPersistentAttribute<O, E>) super.getAttribute();
}
@Override
@ -114,7 +116,8 @@ public class SqmBagJoin<O, E> extends AbstractSqmPluralJoin<O,Collection<E>, E>
@Override
public <S extends E> SqmTreatedBagJoin<O, E, S> treatAs(Class<S> treatAsType) {
final EntityTypeDescriptor<S> entityTypeDescriptor = nodeBuilder().getDomainModel().entity( treatAsType );
return new SqmTreatedBagJoin<>( this, entityTypeDescriptor, null );
final EntityDomainType<S> entityTypeDescriptor = nodeBuilder().getDomainModel().entity( treatAsType );
//noinspection unchecked
return new SqmTreatedBagJoin( this, entityTypeDescriptor, null );
}
}

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.spi.BasicValuedNavigable;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.NodeBuilder;
@ -15,7 +14,7 @@ import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.type.descriptor.java.spi.BasicJavaDescriptor;
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
/**
* @author Steve Ebersole
@ -23,19 +22,19 @@ import org.hibernate.type.descriptor.java.spi.BasicJavaDescriptor;
public class SqmBasicValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
public SqmBasicValuedSimplePath(
NavigablePath navigablePath,
BasicValuedNavigable<T> referencedNavigable,
SqmPathSource<T> referencedPathSource,
SqmPath lhs,
NodeBuilder nodeBuilder) {
this( navigablePath, referencedNavigable, lhs, null, nodeBuilder );
this( navigablePath, referencedPathSource, lhs, null, nodeBuilder );
}
public SqmBasicValuedSimplePath(
NavigablePath navigablePath,
BasicValuedNavigable referencedNavigable,
SqmPathSource<T> referencedPathSource,
SqmPath lhs,
String explicitAlias,
NodeBuilder nodeBuilder) {
super( navigablePath, referencedNavigable, lhs, explicitAlias, nodeBuilder );
super( navigablePath, referencedPathSource, lhs, explicitAlias, nodeBuilder );
}
@Override
@ -53,17 +52,16 @@ public class SqmBasicValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
}
@Override
public SqmPathSource<?, T> getReferencedPathSource() {
return (BasicValuedNavigable<T>) super.getReferencedPathSource();
public SqmPathSource<T> getReferencedPathSource() {
return super.getReferencedPathSource();
}
@Override
public BasicValuedNavigable<T> getNodeType() {
public SqmPathSource<T> getNodeType() {
return getReferencedPathSource();
}
@Override
@SuppressWarnings("unchecked")
public BasicJavaDescriptor<T> getJavaTypeDescriptor() {
return (BasicJavaDescriptor<T>) super.getJavaTypeDescriptor();
}

View File

@ -6,11 +6,11 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.spi.EmbeddedValuedNavigable;
import org.hibernate.metamodel.model.mapping.spi.Navigable;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
@ -20,8 +20,6 @@ import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.sql.ast.produce.metamodel.spi.Joinable;
import org.hibernate.type.descriptor.java.spi.EmbeddableJavaDescriptor;
/**
* @author Steve Ebersole
@ -29,19 +27,24 @@ import org.hibernate.type.descriptor.java.spi.EmbeddableJavaDescriptor;
public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
public SqmEmbeddedValuedSimplePath(
NavigablePath navigablePath,
EmbeddedValuedNavigable<T> referencedNavigable,
SqmPathSource<T> referencedPathSource,
SqmPath lhs,
NodeBuilder nodeBuilder) {
super( navigablePath, referencedNavigable, lhs, nodeBuilder );
super( navigablePath, referencedPathSource, lhs, nodeBuilder );
assert referencedPathSource.getSqmPathType() instanceof EmbeddableDomainType;
}
@SuppressWarnings("unused")
public SqmEmbeddedValuedSimplePath(
NavigablePath navigablePath,
EmbeddedValuedNavigable<T> referencedNavigable,
SqmPathSource<T> referencedPathSource,
SqmPath lhs,
String explicitAlias,
NodeBuilder nodeBuilder) {
super( navigablePath, referencedNavigable, lhs, explicitAlias, nodeBuilder );
super( navigablePath, referencedPathSource, lhs, explicitAlias, nodeBuilder );
assert referencedPathSource.getSqmPathType() instanceof EmbeddableDomainType;
}
@Override
@ -50,33 +53,14 @@ public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
final Navigable subNavigable = getReferencedPathSource().findNavigable( name );
if ( subNavigable == null ) {
final SqmPathSource<?> subPathSource = getReferencedPathSource().findSubPathSource( name );
if ( subPathSource == null ) {
throw UnknownPathException.unknownSubPath( this, name );
}
prepareForSubNavigableReference( subNavigable, isTerminal, creationState );
prepareForSubNavigableReference( subPathSource, isTerminal, creationState );
//noinspection unchecked
return subNavigable.createSqmExpression(
this,
creationState
);
}
@Override
public SqmPathSource<?, T> getReferencedPathSource() {
return (EmbeddedValuedNavigable<T>) super.getReferencedPathSource();
}
@Override
public EmbeddedValuedNavigable<T> getNodeType() {
return getReferencedPathSource();
}
@Override
public EmbeddableJavaDescriptor<T> getJavaTypeDescriptor() {
return getReferencedPathSource().getJavaTypeDescriptor();
return subPathSource.createSqmPath( this, creationState );
}
@Override
@ -88,7 +72,7 @@ public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
@Override
public void prepareForSubNavigableReference(
Navigable subNavigable,
SqmPathSource subNavigable,
boolean isSubReferenceTerminal,
SqmCreationState creationState) {
if ( dereferenced ) {
@ -99,7 +83,7 @@ public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
log.tracef(
"`SqmEmbeddedValuedSimplePath#prepareForSubNavigableReference` : %s -> %s",
getNavigablePath().getFullPath(),
subNavigable.getNavigableName()
subNavigable.getPathName()
);
final SqmPathRegistry pathRegistry = creationState.getProcessingStateStack().getCurrent().getPathRegistry();
@ -109,10 +93,10 @@ public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
if ( fromByPath == null ) {
getLhs().prepareForSubNavigableReference( getReferencedPathSource(), false, creationState );
final SqmFrom lhsFrom = pathRegistry.findFromByPath( getLhs().getNavigablePath() );
final SqmFrom<?,?> lhsFrom = pathRegistry.findFromByPath( getLhs().getNavigablePath() );
if ( getReferencedPathSource() instanceof Joinable ) {
final SqmAttributeJoin sqmJoin = ( (Joinable) getReferencedPathSource() ).createSqmJoin(
if ( getReferencedPathSource() instanceof SqmJoinable ) {
final SqmAttributeJoin sqmJoin = ( (SqmJoinable) getReferencedPathSource() ).createSqmJoin(
lhsFrom,
SqmJoinType.INNER,
null,
@ -120,6 +104,7 @@ public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
creationState
);
pathRegistry.register( sqmJoin );
//noinspection unchecked
lhsFrom.addSqmJoin( sqmJoin );
}
}

View File

@ -6,9 +6,7 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.spi.EntityValuedNavigable;
import org.hibernate.metamodel.model.mapping.spi.Navigable;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.NodeBuilder;
@ -17,7 +15,6 @@ import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.SqmCreationHelper;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.type.descriptor.java.spi.EntityJavaDescriptor;
/**
* @author Steve Ebersole
@ -25,10 +22,10 @@ import org.hibernate.type.descriptor.java.spi.EntityJavaDescriptor;
public class SqmEntityValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
public SqmEntityValuedSimplePath(
NavigablePath navigablePath,
EntityValuedNavigable<T> referencedNavigable,
SqmPathSource<T> referencedPathSource,
SqmPath lhs,
NodeBuilder nodeBuilder) {
super( navigablePath, referencedNavigable, lhs, nodeBuilder );
super( navigablePath, referencedPathSource, lhs, nodeBuilder );
}
@Override
@ -37,17 +34,18 @@ public class SqmEntityValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
final EntityValuedNavigable referencedNavigable = getReferencedPathSource();
final Navigable navigable = referencedNavigable.findNavigable( name );
final SqmPathSource referencedPathSource = getReferencedPathSource();
final SqmPathSource subPathSource = referencedPathSource.findSubPathSource( name );
prepareForSubNavigableReference( referencedNavigable, isTerminal, creationState );
prepareForSubNavigableReference( subPathSource, isTerminal, creationState );
assert getLhs() == null || creationState.getProcessingStateStack()
.getCurrent()
.getPathRegistry()
.findPath( getLhs().getNavigablePath() ) != null;
return navigable.createSqmExpression( this, creationState );
//noinspection unchecked
return subPathSource.createSqmPath( this, creationState );
}
@Override
@ -55,16 +53,11 @@ public class SqmEntityValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
return walker.visitEntityValuedPath( this );
}
@Override
public SqmPathSource<?, T> getReferencedPathSource() {
return (EntityValuedNavigable<T>) super.getReferencedPathSource();
}
private boolean dereferenced;
@Override
public void prepareForSubNavigableReference(
Navigable subNavigable,
SqmPathSource subNavigable,
boolean isSubReferenceTerminal,
SqmCreationState creationState) {
if ( dereferenced ) {
@ -75,7 +68,7 @@ public class SqmEntityValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
log.tracef(
"`SqmEntityValuedSimplePath#prepareForSubNavigableReference` : %s -> %s",
getNavigablePath().getFullPath(),
subNavigable.getNavigableName()
subNavigable.getPathName()
);
SqmCreationHelper.resolveAsLhs( getLhs(), this, subNavigable, isSubReferenceTerminal, creationState );
@ -84,24 +77,16 @@ public class SqmEntityValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
}
@Override
public EntityValuedNavigable<T> getNodeType() {
return getReferencedPathSource();
}
@Override
public EntityJavaDescriptor<T> getJavaTypeDescriptor() {
return getReferencedPathSource().getJavaTypeDescriptor();
public EntityDomainType<T> getNodeType() {
//noinspection unchecked
return (EntityDomainType<T>) getReferencedPathSource().getSqmPathType();
}
@Override
@SuppressWarnings("unchecked")
public <S extends T> SqmTreatedSimplePath<T,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityTypeDescriptor<S> treatTargetDescriptor = nodeBuilder().getDomainModel().entity( treatJavaType );
return new SqmTreatedSimplePath(
this,
treatTargetDescriptor,
nodeBuilder()
);
final EntityDomainType<S> treatTargetDescriptor = nodeBuilder().getDomainModel().entity( treatJavaType );
return new SqmTreatedSimplePath( this, treatTargetDescriptor, nodeBuilder() );
}
}

View File

@ -7,13 +7,11 @@
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.mapping.spi.EntityValuedNavigable;
import org.hibernate.metamodel.model.mapping.spi.Navigable;
import org.hibernate.metamodel.model.mapping.spi.NavigableContainer;
import org.hibernate.metamodel.model.mapping.PersistentCollectionDescriptor;
import org.hibernate.metamodel.model.mapping.spi.PluralValuedNavigable;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
@ -24,27 +22,32 @@ import org.hibernate.query.sqm.tree.expression.SqmExpression;
*/
public class SqmIndexedCollectionAccessPath<T> extends AbstractSqmPath<T> implements SqmPath<T> {
private final SqmExpression<?> selectorExpression;
private final PersistentCollectionDescriptor<?,?,T> collectionDescriptor;
public SqmIndexedCollectionAccessPath(
SqmPath<?> pluralDomainPath,
SqmExpression<?> selectorExpression) {
//noinspection unchecked
super(
pluralDomainPath.getNavigablePath().append( "[]" ),
pluralDomainPath.sqmAs( PluralValuedNavigable.class ).getCollectionDescriptor().getElementDescriptor(),
(PluralPersistentAttribute) pluralDomainPath.getReferencedPathSource(),
pluralDomainPath,
pluralDomainPath.nodeBuilder()
);
this.selectorExpression = selectorExpression;
this.collectionDescriptor = pluralDomainPath.sqmAs( PluralValuedNavigable.class ).getCollectionDescriptor();
}
public SqmExpression getSelectorExpression() {
return selectorExpression;
}
@Override
public PluralPersistentAttribute<?,?,T> getReferencedPathSource() {
//noinspection unchecked
return (PluralPersistentAttribute) super.getReferencedPathSource();
}
@Override
public NavigablePath getNavigablePath() {
// todo (6.0) : this would require some String-ified form of the selector
@ -57,10 +60,9 @@ public class SqmIndexedCollectionAccessPath<T> extends AbstractSqmPath<T> implem
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
final Navigable subNavigable = ( (NavigableContainer) collectionDescriptor.getElementDescriptor() )
.findNavigable( name );
return subNavigable.createSqmExpression( this, creationState );
final SqmPathSource subPathSource = getReferencedPathSource().getElementPathSource().findSubPathSource( name );
//noinspection unchecked
return subPathSource.createSqmPath( this, creationState );
}
@Override
@ -70,7 +72,7 @@ public class SqmIndexedCollectionAccessPath<T> extends AbstractSqmPath<T> implem
@Override
public <S extends T> SqmTreatedPath<T, S> treatAs(Class<S> treatJavaType) throws PathException {
if ( getReferencedPathSource() instanceof EntityValuedNavigable ) {
if ( getReferencedPathSource().getSqmPathType() instanceof EntityDomainType ) {
throw new NotYetImplementedFor6Exception();
}

View File

@ -14,24 +14,24 @@ import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.mapping.spi.BasicValuedNavigable;
import org.hibernate.metamodel.model.mapping.spi.CollectionIndex;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.spi.ListPersistentAttribute;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaListJoin;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.criteria.JpaSubQuery;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
*/
public class SqmListJoin<O,E> extends AbstractSqmPluralJoin<O,List<E>, E> implements JpaListJoin<O, E> {
@SuppressWarnings("WeakerAccess")
public SqmListJoin(
SqmFrom<?,O> lhs,
ListPersistentAttribute<O, E> listAttribute,
@ -42,22 +42,25 @@ public class SqmListJoin<O,E> extends AbstractSqmPluralJoin<O,List<E>, E> implem
super( lhs, listAttribute, alias, sqmJoinType, fetched, nodeBuilder );
}
@Override
public SqmPathSource<?, E> getReferencedPathSource() {
return (ListPersistentAttribute) super.getReferencedPathSource();
}
@Override
public ListPersistentAttribute<O, E> getModel() {
return getReferencedPathSource();
return (ListPersistentAttribute<O, E>) super.getModel();
}
@Override
public JavaTypeDescriptor<E> getJavaTypeDescriptor() {
return getNodeJavaTypeDescriptor();
}
@Override
@SuppressWarnings("unchecked")
public SqmPath<Integer> index() {
final String navigableName = "{index}";
final NavigablePath navigablePath = getNavigablePath().append( navigableName );
//noinspection unchecked
return new SqmBasicValuedSimplePath<>(
getNavigablePath().append( CollectionIndex.NAVIGABLE_NAME ),
(BasicValuedNavigable<Integer>) getReferencedPathSource().getCollectionDescriptor().getIndexDescriptor(),
navigablePath,
( (ListPersistentAttribute) getReferencedPathSource() ).getIndexPathSource(),
this,
nodeBuilder()
);
@ -91,7 +94,7 @@ public class SqmListJoin<O,E> extends AbstractSqmPluralJoin<O,List<E>, E> implem
@Override
@SuppressWarnings("unchecked")
public <S extends E> SqmTreatedListJoin<O,E,S> treatAs(Class<S> treatAsType) {
final EntityTypeDescriptor<S> entityTypeDescriptor = nodeBuilder().getDomainModel().entity( treatAsType );
final EntityDomainType<S> entityTypeDescriptor = nodeBuilder().getDomainModel().entity( treatAsType );
return new SqmTreatedListJoin( this, entityTypeDescriptor, null );
}

View File

@ -6,15 +6,22 @@
*/
package org.hibernate.query.sqm.tree.domain;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.hibernate.metamodel.model.mapping.spi.PluralValuedNavigable;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.sql.ast.produce.metamodel.spi.ExpressableType;
import org.hibernate.type.descriptor.java.spi.BasicJavaDescriptor;
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Represents the reference to a Map attribute's {@link Map.Entry} entries
@ -23,58 +30,114 @@ import org.hibernate.type.descriptor.java.spi.BasicJavaDescriptor;
* @author Gunnar Morling
* @author Steve Ebersole
*/
public class SqmMapEntryReference<K,V> extends AbstractSqmExpression<Map.Entry<K,V>> implements SqmExpression<Map.Entry<K,V>>, ExpressableType<Map.Entry<K,V>> {
public class SqmMapEntryReference<K,V> implements SqmSelectableNode<Map.Entry<K,V>>, Expression<Map.Entry<K,V>> {
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private final SqmPath<?> mapPath;
private final BasicJavaDescriptor<Map.Entry<K,V>> mapEntryTypeDescriptor;
private final NodeBuilder nodeBuilder;
private final JavaTypeDescriptor<Map.Entry<K,V>> mapEntryTypeDescriptor;
private String explicitAlias;
public SqmMapEntryReference(
SqmPath<?> mapPath,
BasicJavaDescriptor<Map.Entry<K,V>> mapEntryTypeDescriptor,
NodeBuilder nodeBuilder) {
super(
mapPath.sqmAs( PluralValuedNavigable.class ).getCollectionDescriptor().getDescribedAttribute(),
nodeBuilder
);
this.mapPath = mapPath;
this.mapEntryTypeDescriptor = mapEntryTypeDescriptor;
}
this.nodeBuilder = nodeBuilder;
public SqmPath getMapPath() {
return mapPath;
}
public PluralValuedNavigable getMapNavigable() {
return mapPath.sqmAs( PluralValuedNavigable.class );
//noinspection unchecked
this.mapEntryTypeDescriptor = (JavaTypeDescriptor) nodeBuilder.getDomainModel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( Map.Entry.class );
}
@Override
public BasicJavaDescriptor<Map.Entry<K,V>> getJavaTypeDescriptor() {
return mapEntryTypeDescriptor;
public String getAlias() {
return explicitAlias;
}
@Override
public ExpressableType<Map.Entry<K,V>> getNodeType() {
public JpaSelection<Map.Entry<K, V>> alias(String name) {
this.explicitAlias = name;
return this;
}
@Override
public <T> T accept(SemanticQueryWalker<T> walker) {
public JavaTypeDescriptor<Map.Entry<K, V>> getJavaTypeDescriptor() {
return mapEntryTypeDescriptor;
}
@Override
public JavaTypeDescriptor<Map.Entry<K, V>> getNodeJavaTypeDescriptor() {
return mapEntryTypeDescriptor;
}
@Override
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitMapEntryFunction( this );
}
@Override
public String asLoggableText() {
return "MAP_ENTRY(" + getMapNavigable().asLoggableText() + ")";
public void visitSubSelectableNodes(Consumer<SqmSelectableNode<?>> jpaSelectionConsumer) {
}
@Override
public PersistenceType getPersistenceType() {
return PersistenceType.BASIC;
public boolean isCompoundSelection() {
return false;
}
@Override
@SuppressWarnings("unchecked")
public Class<Map.Entry<K,V>> getJavaType() {
return (Class) Map.Entry.class;
public List<? extends JpaSelection<?>> getSelectionItems() {
return Collections.emptyList();
}
@Override
public SqmExpressable<Map.Entry<K, V>> getNodeType() {
return null;
}
@Override
public NodeBuilder nodeBuilder() {
return nodeBuilder;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA (ugh)
@Override
public Predicate isNull() {
throw new UnsupportedOperationException( "Whatever JPA" );
}
@Override
public Predicate isNotNull() {
throw new UnsupportedOperationException( "Whatever JPA" );
}
@Override
public Predicate in(Object... values) {
throw new UnsupportedOperationException( "Whatever JPA" );
}
@Override
public Predicate in(Expression<?>... values) {
throw new UnsupportedOperationException( "Whatever JPA" );
}
@Override
public Predicate in(Collection<?> values) {
throw new UnsupportedOperationException( "Whatever JPA" );
}
@Override
public Predicate in(Expression<Collection<?>> values) {
throw new UnsupportedOperationException( "Whatever JPA" );
}
@Override
public <X> Expression<X> as(Class<X> type) {
throw new UnsupportedOperationException( "Whatever JPA" );
}
}

View File

@ -11,13 +11,10 @@ import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import org.hibernate.metamodel.model.mapping.spi.BasicValuedNavigable;
import org.hibernate.metamodel.model.mapping.spi.CollectionElement;
import org.hibernate.metamodel.model.mapping.spi.CollectionIndex;
import org.hibernate.metamodel.model.mapping.spi.EmbeddedValuedNavigable;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.spi.EntityValuedNavigable;
import org.hibernate.metamodel.model.mapping.spi.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaMapJoin;
@ -28,12 +25,13 @@ import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.type.descriptor.java.spi.BasicJavaDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
*/
public class SqmMapJoin<O,K,V> extends AbstractSqmPluralJoin<O,Map<K,V>,V> implements JpaMapJoin<O,K,V> {
@SuppressWarnings("WeakerAccess")
public SqmMapJoin(
SqmFrom<?,O> lhs,
MapPersistentAttribute<O,K,V> pluralValuedNavigable,
@ -45,10 +43,16 @@ public class SqmMapJoin<O,K,V> extends AbstractSqmPluralJoin<O,Map<K,V>,V> imple
}
@Override
public SqmPathSource<?, V> getReferencedPathSource() {
public MapPersistentAttribute<O,K,V> getReferencedPathSource() {
//noinspection unchecked
return(MapPersistentAttribute) super.getReferencedPathSource();
}
@Override
public JavaTypeDescriptor<V> getJavaTypeDescriptor() {
return getNodeJavaTypeDescriptor();
}
@Override
public MapPersistentAttribute<O,K,V> getModel() {
return (MapPersistentAttribute<O, K, V>) super.getModel();
@ -61,86 +65,79 @@ public class SqmMapJoin<O,K,V> extends AbstractSqmPluralJoin<O,Map<K,V>,V> imple
@Override
@SuppressWarnings("unchecked")
public SqmPath<K> key() {
final CollectionIndex mapKeyDescriptor = getReferencedPathSource().getCollectionDescriptor().getIndexDescriptor();
final NavigablePath navigablePath = getNavigablePath().append( mapKeyDescriptor.getNavigableName() );
final SqmPathSource keyPathSource = getReferencedPathSource().getKeyPathSource();
final NavigablePath navigablePath = getNavigablePath().append( keyPathSource.getPathName() );
if ( mapKeyDescriptor instanceof BasicValuedNavigable ) {
if ( keyPathSource.getSqmPathType() instanceof BasicDomainType ) {
return new SqmBasicValuedSimplePath(
navigablePath,
(BasicValuedNavigable) mapKeyDescriptor,
keyPathSource,
this,
null
);
}
if ( mapKeyDescriptor instanceof EmbeddedValuedNavigable ) {
if ( keyPathSource.getSqmPathType() instanceof EmbeddableDomainType ) {
return new SqmEmbeddedValuedSimplePath(
navigablePath,
(EmbeddedValuedNavigable) mapKeyDescriptor,
keyPathSource,
this,
null
);
}
if ( mapKeyDescriptor instanceof EntityValuedNavigable ) {
if ( keyPathSource.getSqmPathType() instanceof EntityDomainType ) {
return new SqmEntityValuedSimplePath(
navigablePath,
(EntityValuedNavigable) mapKeyDescriptor,
keyPathSource,
this,
null
);
}
throw new UnsupportedOperationException( "Unrecognized Map key descriptor : " + mapKeyDescriptor );
throw new UnsupportedOperationException( "Unrecognized Map key descriptor : " + keyPathSource );
}
@Override
@SuppressWarnings("unchecked")
public Path<V> value() {
final CollectionElement valueDescriptor = getReferencedPathSource().getCollectionDescriptor().getElementDescriptor();
final NavigablePath navigablePath = getNavigablePath().append( valueDescriptor.getNavigableName() );
final SqmPathSource elementPathSource = getReferencedPathSource().getElementPathSource();
final NavigablePath navigablePath = getNavigablePath().append( elementPathSource.getPathName() );
if ( valueDescriptor instanceof BasicValuedNavigable ) {
if ( elementPathSource.getSqmPathType() instanceof BasicDomainType ) {
return new SqmBasicValuedSimplePath(
navigablePath,
(BasicValuedNavigable) valueDescriptor,
elementPathSource,
this,
null
);
}
if ( valueDescriptor instanceof EmbeddedValuedNavigable ) {
if ( elementPathSource.getSqmPathType() instanceof EmbeddableDomainType ) {
return new SqmEmbeddedValuedSimplePath(
navigablePath,
(EmbeddedValuedNavigable) valueDescriptor,
elementPathSource,
this,
null
);
}
if ( valueDescriptor instanceof EntityValuedNavigable ) {
if ( elementPathSource.getSqmPathType() instanceof EntityDomainType ) {
return new SqmEntityValuedSimplePath(
navigablePath,
(EntityValuedNavigable) valueDescriptor,
elementPathSource,
this,
null
);
}
throw new UnsupportedOperationException( "Unrecognized Map value descriptor : " + valueDescriptor );
throw new UnsupportedOperationException( "Unrecognized Map value descriptor : " + elementPathSource );
}
@Override
@SuppressWarnings("unchecked")
public Expression<Map.Entry<K, V>> entry() {
return new SqmMapEntryReference<>(
this,
(BasicJavaDescriptor) nodeBuilder().getDomainModel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( Map.Entry.class ),
nodeBuilder()
);
return new SqmMapEntryReference( this, nodeBuilder() );
}
@Override
@ -171,7 +168,7 @@ public class SqmMapJoin<O,K,V> extends AbstractSqmPluralJoin<O,Map<K,V>,V> imple
@Override
@SuppressWarnings("unchecked")
public <S extends V> SqmTreatedMapJoin<O,K,V,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityTypeDescriptor<S> targetDescriptor = nodeBuilder().getDomainModel().entity( treatJavaType );
final EntityDomainType<S> targetDescriptor = nodeBuilder().getDomainModel().entity( treatJavaType );
return new SqmTreatedMapJoin( this, targetDescriptor, null );
}
}

View File

@ -6,9 +6,8 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.spi.Navigable;
import org.hibernate.metamodel.model.mapping.spi.NavigableContainer;
import org.hibernate.metamodel.model.mapping.PersistentCollectionDescriptor;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
@ -22,10 +21,11 @@ public class SqmMaxElementPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
public static final String NAVIGABLE_NAME = "{max-element}";
public SqmMaxElementPath(SqmPath<?> pluralDomainPath) {
//noinspection unchecked
super(
pluralDomainPath.getNavigablePath().append( NAVIGABLE_NAME ),
pluralDomainPath,
pluralDomainPath.sqmAs( PersistentCollectionDescriptor.class ).getElementDescriptor()
(PluralPersistentAttribute) pluralDomainPath.getReferencedPathSource()
);
}
@ -35,18 +35,18 @@ public class SqmMaxElementPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
if ( getReferencedPathSource() instanceof NavigableContainer<?> ) {
final Navigable subNavigable = ( (NavigableContainer) getReferencedPathSource() ).findNavigable( name );
getPluralDomainPath().prepareForSubNavigableReference( subNavigable, isTerminal, creationState );
return subNavigable.createSqmExpression( this, creationState );
if ( getPluralAttribute().getElementPathSource().getSqmPathType() instanceof ManagedDomainType ) {
//noinspection unchecked
return getPluralAttribute().getElementPathSource().createSqmPath( this, creationState );
}
throw new SemanticException( "Collection element cannot be de-referenced : " + getPluralDomainPath().getNavigablePath() );
}
@Override
public SqmPathSource<?, T> getReferencedPathSource() {
return getCollectionDescriptor().getElementDescriptor();
public SqmPathSource<T> getReferencedPathSource() {
//noinspection unchecked
return getPluralAttribute().getElementPathSource();
}
@Override

View File

@ -6,10 +6,9 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.spi.Navigable;
import org.hibernate.metamodel.model.mapping.spi.NavigableContainer;
import org.hibernate.metamodel.model.mapping.PersistentCollectionDescriptor;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
@ -21,12 +20,27 @@ import org.hibernate.query.sqm.produce.spi.SqmCreationState;
public class SqmMaxIndexPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
public static final String NAVIGABLE_NAME = "{max-index}";
private final SqmPathSource<T> indexPathSource;
public SqmMaxIndexPath(SqmPath<?> pluralDomainPath) {
//noinspection unchecked
super(
pluralDomainPath.getNavigablePath().append( NAVIGABLE_NAME ),
pluralDomainPath,
pluralDomainPath.sqmAs( PersistentCollectionDescriptor.class ).getIndexDescriptor()
(PluralPersistentAttribute<?, ?, T>) pluralDomainPath.getReferencedPathSource()
);
if ( getPluralAttribute() instanceof ListPersistentAttribute ) {
//noinspection unchecked
this.indexPathSource = ( (ListPersistentAttribute) getPluralAttribute() ).getIndexPathSource();
}
else if ( getPluralAttribute() instanceof MapPersistentAttribute ) {
//noinspection unchecked
this.indexPathSource = ( (MapPersistentAttribute) getPluralAttribute() ).getKeyPathSource();
}
else {
throw new UnsupportedOperationException( "Plural attribute [" + getPluralAttribute() + "] is not indexed" );
}
}
@Override
@ -35,18 +49,12 @@ public class SqmMaxIndexPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
if ( getReferencedPathSource() instanceof NavigableContainer<?> ) {
final Navigable subNavigable = ( (NavigableContainer) getReferencedPathSource() ).findNavigable( name );
getPluralDomainPath().prepareForSubNavigableReference( subNavigable, isTerminal, creationState );
return subNavigable.createSqmExpression( this, creationState );
}
throw new SemanticException( "Collection index cannot be de-referenced : " + getPluralDomainPath().getNavigablePath() );
return indexPathSource.createSqmPath( this, creationState );
}
@Override
public SqmPathSource<?, T> getReferencedPathSource() {
return getCollectionDescriptor().getIndexDescriptor();
public SqmPathSource<T> getReferencedPathSource() {
return indexPathSource;
}
@Override

View File

@ -6,9 +6,8 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.spi.Navigable;
import org.hibernate.metamodel.model.mapping.spi.NavigableContainer;
import org.hibernate.metamodel.model.mapping.PersistentCollectionDescriptor;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
@ -22,10 +21,11 @@ public class SqmMinElementPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
public static final String NAVIGABLE_NAME = "{min-element}";
public SqmMinElementPath(SqmPath<?> pluralDomainPath) {
//noinspection unchecked
super(
pluralDomainPath.getNavigablePath().append( NAVIGABLE_NAME ),
pluralDomainPath,
pluralDomainPath.sqmAs( PersistentCollectionDescriptor.class ).getElementDescriptor()
(PluralPersistentAttribute) pluralDomainPath.getReferencedPathSource()
);
}
@ -35,18 +35,18 @@ public class SqmMinElementPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
if ( getReferencedPathSource() instanceof NavigableContainer<?> ) {
final Navigable subNavigable = ( (NavigableContainer) getReferencedPathSource() ).findNavigable( name );
getPluralDomainPath().prepareForSubNavigableReference( subNavigable, isTerminal, creationState );
return subNavigable.createSqmExpression( this, creationState );
if ( getPluralAttribute().getElementPathSource().getSqmPathType() instanceof ManagedDomainType ) {
//noinspection unchecked
return getPluralAttribute().getElementPathSource().createSqmPath( this, creationState );
}
throw new SemanticException( "Collection element cannot be de-referenced : " + getPluralDomainPath().getNavigablePath() );
}
@Override
public SqmPathSource<?, T> getReferencedPathSource() {
return getCollectionDescriptor().getElementDescriptor();
public SqmPathSource<T> getReferencedPathSource() {
//noinspection unchecked
return getPluralAttribute().getElementPathSource();
}
@Override

View File

@ -6,10 +6,9 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.spi.Navigable;
import org.hibernate.metamodel.model.mapping.spi.NavigableContainer;
import org.hibernate.metamodel.model.mapping.PersistentCollectionDescriptor;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
@ -21,12 +20,27 @@ import org.hibernate.query.sqm.produce.spi.SqmCreationState;
public class SqmMinIndexPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
public static final String NAVIGABLE_NAME = "{min-index}";
private final SqmPathSource<T> indexPathSource;
public SqmMinIndexPath(SqmPath<?> pluralDomainPath) {
//noinspection unchecked
super(
pluralDomainPath.getNavigablePath().append( NAVIGABLE_NAME ),
pluralDomainPath,
pluralDomainPath.sqmAs( PersistentCollectionDescriptor.class ).getIndexDescriptor()
(PluralPersistentAttribute<?, ?, T>) pluralDomainPath.getReferencedPathSource()
);
if ( getPluralAttribute() instanceof ListPersistentAttribute ) {
//noinspection unchecked
this.indexPathSource = ( (ListPersistentAttribute) getPluralAttribute() ).getIndexPathSource();
}
else if ( getPluralAttribute() instanceof MapPersistentAttribute ) {
//noinspection unchecked
this.indexPathSource = ( (MapPersistentAttribute) getPluralAttribute() ).getKeyPathSource();
}
else {
throw new UnsupportedOperationException( "Plural attribute [" + getPluralAttribute() + "] is not indexed" );
}
}
@Override
@ -35,18 +49,12 @@ public class SqmMinIndexPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
if ( getReferencedPathSource() instanceof NavigableContainer<?> ) {
final Navigable subNavigable = ( (NavigableContainer) getReferencedPathSource() ).findNavigable( name );
getPluralDomainPath().prepareForSubNavigableReference( subNavigable, isTerminal, creationState );
return subNavigable.createSqmExpression( this, creationState );
}
throw new SemanticException( "Collection index cannot be de-referenced : " + getPluralDomainPath().getNavigablePath() );
return indexPathSource.createSqmPath( this, creationState );
}
@Override
public SqmPathSource<?, T> getReferencedPathSource() {
return getCollectionDescriptor().getIndexDescriptor();
public SqmPathSource<T> getReferencedPathSource() {
return indexPathSource;
}
@Override

View File

@ -6,10 +6,6 @@
*/
package org.hibernate.query.sqm.tree.domain;
import java.util.Locale;
import java.util.function.Supplier;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.JpaPath;
import org.hibernate.query.criteria.PathException;
@ -61,7 +57,7 @@ public interface SqmPath<T> extends SqmExpression<T>, SemanticPathPart, JpaPath<
SqmPath<?> getLhs();
@Override
DomainType<T> getNodeType();
SqmPathSource<T> getNodeType();
@Override
default void applyInferableType(SqmExpressable<T> type) {
@ -70,7 +66,7 @@ public interface SqmPath<T> extends SqmExpression<T>, SemanticPathPart, JpaPath<
@Override
default JavaTypeDescriptor<T> getJavaTypeDescriptor() {
return getNodeType().getJavaTypeDescriptor();
return getNodeType().getExpressableJavaTypeDescriptor();
}
@Override
@ -140,45 +136,48 @@ public interface SqmPath<T> extends SqmExpression<T>, SemanticPathPart, JpaPath<
SqmCreationHelper.resolveAsLhs( getLhs(), this, subNavigable, isSubReferenceTerminal, creationState );
}
/**
* Treat this path as the given type. "Cast it" to the target type.
*
* May throw an exception if the Path is not treatable as the requested type.
*
* Also recognizes any {@link Navigable} target type and applies it to the
* {@link #getReferencedPathSource()}.
*
* @apiNote This is very different from JPA's {@link #as} (and variants like
* {@link #asInteger()}, etc) which are equivalent to SQL CAST function calls.
*
* @return The "casted" reference
*/
@SuppressWarnings("unchecked")
default <X> X sqmAs(Class<X> targetType) {
if ( targetType.isInstance( this ) ) {
return (X) this;
}
if ( Navigable.class.isAssignableFrom( targetType ) ) {
return (X) ( (Navigable) getReferencedPathSource() ).as( targetType );
}
throw new IllegalArgumentException(
String.format(
Locale.ROOT,
"`%s` cannot be treated as `%s`",
getClass().getName(),
targetType.getName()
)
);
}
default <X> X sqmAs(Class<X> targetType, Supplier<RuntimeException> exceptionSupplier) {
try {
return sqmAs( targetType );
}
catch (IllegalArgumentException e) {
throw exceptionSupplier.get();
}
}
// /**
// * Treat this path as the given type. "Cast it" to the target type.
// *
// * May throw an exception if the Path is not treatable as the requested type.
// *
// * Also recognizes any {@link Navigable} target type and applies it to the
// * {@link #getReferencedPathSource()}.
// *
// * @apiNote This is very different from JPA's {@link #as} (and variants like
// * {@link #asInteger()}, etc) which are equivalent to SQL CAST function calls.
// *
// * @return The "casted" reference
// */
// @SuppressWarnings("unchecked")
// default <X> X sqmAs(Class<X> targetType) {
// if ( targetType.isInstance( this ) ) {
// return (X) this;
// }
//
// if ( getReferencedPathSource().getSqmPathType()
// .getExpressableJavaTypeDescriptor()
// .getJavaType()
// .isAssignableFrom( targetType ) ) {
// return (X) ( (Navigable) getReferencedPathSource() ).as( targetType );
// }
//
// throw new IllegalArgumentException(
// String.format(
// Locale.ROOT,
// "`%s` cannot be treated as `%s`",
// getClass().getName(),
// targetType.getName()
// )
// );
// }
//
// default <X> X sqmAs(Class<X> targetType, Supplier<RuntimeException> exceptionSupplier) {
// try {
// return sqmAs( targetType );
// }
// catch (IllegalArgumentException e) {
// throw exceptionSupplier.get();
// }
// }
}

View File

@ -6,21 +6,23 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.mapping.spi.CollectionElement;
import org.hibernate.metamodel.model.mapping.spi.CollectionIndex;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.spi.PluralValuedNavigable;
import org.hibernate.persister.collection.CollectionPropertyNames;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.type.descriptor.java.internal.CollectionJavaDescriptor;
/**
* An SqmPath for plural attribute paths
*
* @param <E> The collection element type, which is the "bindable" type in the SQM tree
*
* @author Steve Ebersole
*/
public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
@ -32,16 +34,35 @@ public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
this( navigablePath, referencedNavigable, lhs, null, nodeBuilder );
}
@SuppressWarnings("WeakerAccess")
public SqmPluralValuedSimplePath(
NavigablePath navigablePath,
PluralPersistentAttribute referencedNavigable,
SqmPath lhs,
String explicitAlias,
NodeBuilder nodeBuilder) {
//noinspection unchecked
super( navigablePath, referencedNavigable, lhs, explicitAlias, nodeBuilder );
}
@Override
public PluralPersistentAttribute<?,?,E> getReferencedPathSource() {
//noinspection unchecked
return (PluralPersistentAttribute) super.getReferencedPathSource();
}
@Override
public PluralPersistentAttribute<?,?,E> getNodeType() {
return getReferencedPathSource();
}
@Override
public <T> T accept(SemanticQueryWalker<T> walker) {
return walker.visitPluralValuedPath( this );
}
@Override
@SuppressWarnings("unchecked")
public SemanticPathPart resolvePathPart(
String name,
String currentContextKey,
@ -62,21 +83,28 @@ public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
return creationState.getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
navigablePath,
np -> {
if ( CollectionElement.NAVIGABLE_NAME.equals( name ) ) {
return getReferencedPathSource().getCollectionDescriptor().getElementDescriptor().createSqmExpression(
final PluralPersistentAttribute<?, ?, E> referencedPathSource = getReferencedPathSource();
if ( CollectionPropertyNames.COLLECTION_ELEMENTS.equals( name ) ) {
return referencedPathSource.getElementPathSource().createSqmPath(
this,
creationState
);
}
if ( CollectionIndex.NAVIGABLE_NAME.equals( name ) ) {
return getReferencedPathSource().getCollectionDescriptor().getIndexDescriptor().createSqmExpression(
this,
creationState
);
if ( CollectionPropertyNames.COLLECTION_INDEX.equals( name )
|| CollectionPropertyNames.COLLECTION_INDICES.equals( name ) ) {
if ( referencedPathSource instanceof MapPersistentAttribute ) {
return ( (MapPersistentAttribute) referencedPathSource ).getKeyPathSource().createSqmPath( this, creationState );
}
else if ( referencedPathSource instanceof ListPersistentAttribute ) {
return ( (ListPersistentAttribute) referencedPathSource ).getIndexPathSource().createSqmPath( this, creationState );
}
throw new UnsupportedOperationException( );
}
return getReferencedPathSource().getCollectionDescriptor().getElementDescriptor().createSqmExpression(
return referencedPathSource.getElementPathSource().createSqmPath(
this,
creationState
);
@ -84,17 +112,28 @@ public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
);
}
@Override
@SuppressWarnings("unchecked")
public <S extends E> SqmTreatedSimplePath<E,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityDomainType<S> treatTargetDescriptor = nodeBuilder().getDomainModel().entity( treatJavaType );
return new SqmTreatedSimplePath(
this,
treatTargetDescriptor,
nodeBuilder()
);
}
// @Override
// public DomainResult createDomainResult(
// String resultVariable,
// DomainResultCreationState creationState,
// DomainResultCreationContext creationContext) {
// return new CollectionResultImpl(
// getReferencedNavigable().getCollectionDescriptor().getDescribedAttribute(),
// getReferencedNavigable().getPluralAttribute().getDescribedAttribute(),
// getNavigablePath(),
// resultVariable,
// LockMode.NONE,
// getReferencedNavigable().getCollectionDescriptor().getCollectionKeyDescriptor().createDomainResult(
// getReferencedNavigable().getPluralAttribute().getCollectionKeyDescriptor().createDomainResult(
// getNavigablePath().append( "{id}" ),
// null,
// creationState,
@ -104,34 +143,4 @@ public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
// );
// }
@Override
public <T> T accept(SemanticQueryWalker<T> walker) {
return walker.visitPluralValuedPath( this );
}
@Override
public SqmPathSource<?, E> getReferencedPathSource() {
return (PluralValuedNavigable<E>) super.getReferencedPathSource();
}
@Override
public PluralValuedNavigable<E> getNodeType() {
return getReferencedPathSource();
}
@Override
public CollectionJavaDescriptor getJavaTypeDescriptor() {
return (CollectionJavaDescriptor) super.getJavaTypeDescriptor();
}
@Override
@SuppressWarnings("unchecked")
public <S extends E> SqmTreatedSimplePath<E,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityTypeDescriptor<S> treatTargetDescriptor = nodeBuilder().getDomainModel().entity( treatJavaType );
return new SqmTreatedSimplePath(
this,
treatTargetDescriptor,
nodeBuilder()
);
}
}

View File

@ -14,17 +14,17 @@ import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.spi.SetPersistentAttribute;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.SetPersistentAttribute;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.criteria.JpaSetJoin;
import org.hibernate.query.criteria.JpaSubQuery;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
@ -32,6 +32,7 @@ import org.hibernate.query.sqm.tree.from.SqmFrom;
public class SqmSetJoin<O, E>
extends AbstractSqmPluralJoin<O,Set<E>, E>
implements JpaSetJoin<O, E> {
@SuppressWarnings("WeakerAccess")
public SqmSetJoin(
SqmFrom<?,O> lhs,
SetPersistentAttribute<O, E> pluralValuedNavigable,
@ -43,10 +44,16 @@ public class SqmSetJoin<O, E>
}
@Override
public SqmPathSource<?, E> getReferencedPathSource() {
public SetPersistentAttribute<O,E> getReferencedPathSource() {
//noinspection unchecked
return (SetPersistentAttribute) super.getReferencedPathSource();
}
@Override
public JavaTypeDescriptor<E> getJavaTypeDescriptor() {
return getReferencedPathSource().getExpressableJavaTypeDescriptor();
}
@Override
public SetPersistentAttribute<O,E> getModel() {
return getReferencedPathSource();
@ -84,7 +91,7 @@ public class SqmSetJoin<O, E>
@Override
public <S extends E> SqmTreatedSetJoin<O,E,S> treatAs(Class<S> treatAsType) {
final EntityTypeDescriptor<S> entityTypeDescriptor = nodeBuilder().getDomainModel().entity( treatAsType );
final EntityDomainType<S> entityTypeDescriptor = nodeBuilder().getDomainModel().entity( treatAsType );
return new SqmTreatedSetJoin<>( this, entityTypeDescriptor, null );
}

View File

@ -9,11 +9,12 @@ package org.hibernate.query.sqm.tree.domain;
import java.util.Locale;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
@ -21,7 +22,7 @@ import org.hibernate.query.sqm.tree.from.SqmFrom;
public class SqmSingularJoin<O,T> extends AbstractSqmAttributeJoin<O,T> {
public SqmSingularJoin(
SqmFrom<?,O> lhs,
SqmJoinable<O,T,T> joinedNavigable,
SingularPersistentAttribute<O, T> joinedNavigable,
String alias,
SqmJoinType joinType,
boolean fetched,
@ -29,10 +30,16 @@ public class SqmSingularJoin<O,T> extends AbstractSqmAttributeJoin<O,T> {
super( lhs, joinedNavigable, alias, joinType, fetched, nodeBuilder );
}
@Override
public JavaTypeDescriptor<T> getJavaTypeDescriptor() {
return getNodeJavaTypeDescriptor();
}
@Override
public <S extends T> SqmTreatedSingularJoin<O,T,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityDomainType<S> targetDescriptor = nodeBuilder().getDomainModel().entity( treatJavaType );
return new SqmTreatedSingularJoin<>( this, targetDescriptor, null );
//noinspection unchecked
return new SqmTreatedSingularJoin( this, targetDescriptor, null );
}
@Override

View File

@ -6,21 +6,20 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.spi.BagPersistentAttribute;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.metamodel.model.domain.BagPersistentAttribute;
import org.hibernate.metamodel.model.domain.EntityDomainType;
/**
* @author Steve Ebersole
*/
public class SqmTreatedBagJoin<O,T, S extends T> extends SqmBagJoin<O,S> implements SqmTreatedPath<T,S> {
private final SqmBagJoin<O, T> wrappedPath;
private final EntityTypeDescriptor<S> treatTarget;
private final EntityDomainType<S> treatTarget;
@SuppressWarnings("unchecked")
public SqmTreatedBagJoin(
SqmBagJoin<O,T> wrappedPath,
EntityTypeDescriptor<S> treatTarget,
EntityDomainType<S> treatTarget,
String alias) {
super(
wrappedPath.getLhs(),
@ -40,19 +39,7 @@ public class SqmTreatedBagJoin<O,T, S extends T> extends SqmBagJoin<O,S> impleme
}
@Override
public EntityTypeDescriptor<S> getTreatTarget() {
public EntityDomainType<S> getTreatTarget() {
return treatTarget;
}
@Override
@SuppressWarnings("unchecked")
public SqmPathSource<?, S> getReferencedPathSource() {
return super.getReferencedPathSource();
}
@Override
@SuppressWarnings("unchecked")
public BagPersistentAttribute getModel() {
return getReferencedPathSource();
}
}

View File

@ -6,8 +6,7 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.tree.from.SqmCrossJoin;
/**
@ -15,14 +14,15 @@ import org.hibernate.query.sqm.tree.from.SqmCrossJoin;
*/
public class SqmTreatedCrossJoin<T,S extends T> extends SqmCrossJoin<S> implements SqmTreatedPath<T,S> {
private final SqmCrossJoin<T> wrappedPath;
private final EntityTypeDescriptor<S> treatTarget;
private final EntityDomainType<S> treatTarget;
public SqmTreatedCrossJoin(
SqmCrossJoin<T> wrappedPath,
String alias,
EntityTypeDescriptor<S> treatTarget) {
EntityDomainType<S> treatTarget) {
//noinspection unchecked
super(
(EntityTypeDescriptor) wrappedPath.getReferencedPathSource(),
(EntityDomainType) wrappedPath.getReferencedPathSource().getSqmPathType(),
alias,
wrappedPath.getRoot()
);
@ -31,12 +31,12 @@ public class SqmTreatedCrossJoin<T,S extends T> extends SqmCrossJoin<S> implemen
}
@Override
public EntityTypeDescriptor<S> getTreatTarget() {
public EntityDomainType<S> getTreatTarget() {
return treatTarget;
}
@Override
public EntityTypeDescriptor<S> getModel() {
public EntityDomainType<S> getModel() {
return getTreatTarget();
}
@ -46,7 +46,8 @@ public class SqmTreatedCrossJoin<T,S extends T> extends SqmCrossJoin<S> implemen
}
@Override
public SqmPathSource<?, S> getReferencedPathSource() {
return (EntityTypeDescriptor<S>) wrappedPath.getReferencedPathSource();
public EntityDomainType<S> getReferencedPathSource() {
//noinspection unchecked
return (EntityDomainType) wrappedPath.getReferencedPathSource();
}
}

View File

@ -6,8 +6,7 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
@ -16,11 +15,11 @@ import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
*/
public class SqmTreatedEntityJoin<T, S extends T> extends SqmEntityJoin<S> implements SqmTreatedPath<T,S> {
private final SqmEntityJoin<T> wrapped;
private final EntityTypeDescriptor<S> treatTarget;
private final EntityDomainType<S> treatTarget;
public SqmTreatedEntityJoin(
SqmEntityJoin<T> wrapped,
EntityTypeDescriptor<S> treatTarget,
EntityDomainType<S> treatTarget,
String alias,
SqmJoinType joinType) {
super(
@ -34,7 +33,7 @@ public class SqmTreatedEntityJoin<T, S extends T> extends SqmEntityJoin<S> imple
}
@Override
public EntityTypeDescriptor<S> getTreatTarget() {
public EntityDomainType<S> getTreatTarget() {
return treatTarget;
}
@ -44,7 +43,8 @@ public class SqmTreatedEntityJoin<T, S extends T> extends SqmEntityJoin<S> imple
}
@Override
public SqmPathSource<?, S> getReferencedPathSource() {
return super.getReferencedPathSource();
public EntityDomainType<S> getReferencedPathSource() {
//noinspection unchecked
return (EntityDomainType<S>) wrapped.getReferencedPathSource();
}
}

View File

@ -6,20 +6,21 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.spi.ListPersistentAttribute;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
/**
* @author Steve Ebersole
*/
public class SqmTreatedListJoin<O,T, S extends T> extends SqmListJoin<O,S> implements SqmTreatedPath<T,S> {
private final SqmListJoin<O,T> wrappedPath;
private final EntityTypeDescriptor<S> treatTarget;
private final EntityDomainType<S> treatTarget;
public SqmTreatedListJoin(
SqmListJoin<O,T> wrappedPath,
EntityTypeDescriptor<S> treatTarget,
EntityDomainType<S> treatTarget,
String alias) {
//noinspection unchecked
super(
@ -40,19 +41,21 @@ public class SqmTreatedListJoin<O,T, S extends T> extends SqmListJoin<O,S> imple
}
@Override
public EntityTypeDescriptor<S> getTreatTarget() {
public ListPersistentAttribute<O, S> getModel() {
return (ListPersistentAttribute<O, S>) super.getModel();
}
@Override
public EntityDomainType<S> getTreatTarget() {
return treatTarget;
}
@Override
@SuppressWarnings("unchecked")
public SqmPathSource<?, S> getReferencedPathSource() {
return super.getReferencedPathSource();
}
@Override
@SuppressWarnings("unchecked")
public ListPersistentAttribute getModel() {
return getReferencedPathSource();
public SqmPath resolveIndexedAccess(
SqmExpression selector,
String currentContextKey,
boolean isTerminal,
SqmCreationState creationState) {
return getWrappedPath().resolveIndexedAccess( selector, currentContextKey, isTerminal, creationState );
}
}

View File

@ -6,25 +6,24 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.spi.MapPersistentAttribute;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
*/
public class SqmTreatedMapJoin<O,K,V, S extends V> extends SqmMapJoin<O,K,S> implements SqmTreatedPath<V,S> {
private final SqmMapJoin<O,K,V> wrappedPath;
private final EntityTypeDescriptor<S> treatTarget;
private final EntityDomainType<S> treatTarget;
public SqmTreatedMapJoin(
SqmMapJoin<O,K,V> wrappedPath,
EntityTypeDescriptor<S> treatTarget,
EntityDomainType<S> treatTarget,
String alias) {
//noinspection unchecked
super(
wrappedPath.getLhs(),
(MapPersistentAttribute) wrappedPath.getAttribute(),
( (SqmMapJoin) wrappedPath ).getModel(),
alias,
wrappedPath.getSqmJoinType(),
wrappedPath.isFetched(),
@ -40,13 +39,12 @@ public class SqmTreatedMapJoin<O,K,V, S extends V> extends SqmMapJoin<O,K,S> imp
}
@Override
public EntityTypeDescriptor<S> getTreatTarget() {
public EntityDomainType<S> getTreatTarget() {
return treatTarget;
}
@Override
@SuppressWarnings("unchecked")
public SqmPathSource<?, S> getReferencedPathSource() {
return super.getReferencedPathSource();
public JavaTypeDescriptor<S> getJavaTypeDescriptor() {
return null;
}
}

View File

@ -6,13 +6,13 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.domain.EntityDomainType;
/**
* @author Steve Ebersole
*/
public interface SqmTreatedPath<T, S extends T> extends SqmPathWrapper<T, S> {
EntityTypeDescriptor<S> getTreatTarget();
EntityDomainType<S> getTreatTarget();
@Override
SqmPath<T> getWrappedPath();

View File

@ -6,10 +6,8 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.spi.EntityValuedNavigable;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.from.SqmRoot;
/**
@ -17,15 +15,15 @@ import org.hibernate.query.sqm.tree.from.SqmRoot;
*/
public class SqmTreatedRoot<T, S extends T> extends SqmRoot<S> implements SqmTreatedPath<T,S> {
private final SqmRoot<T> wrappedPath;
private final EntityTypeDescriptor<S> treatTarget;
private final EntityDomainType<S> treatTarget;
public SqmTreatedRoot(
SqmRoot<T> wrappedPath,
EntityTypeDescriptor<S> treatTarget,
EntityDomainType<S> treatTarget,
NodeBuilder nodeBuilder) {
//noinspection unchecked
super(
( (EntityValuedNavigable) wrappedPath.getReferencedPathSource() ).getEntityDescriptor(),
(EntityDomainType) wrappedPath.getReferencedPathSource(),
null,
nodeBuilder
);
@ -34,12 +32,12 @@ public class SqmTreatedRoot<T, S extends T> extends SqmRoot<S> implements SqmTre
}
@Override
public EntityTypeDescriptor<S> getTreatTarget() {
public EntityDomainType<S> getTreatTarget() {
return treatTarget;
}
@Override
public EntityTypeDescriptor<S> getManagedType() {
public EntityDomainType<S> getManagedType() {
return getTreatTarget();
}
@ -49,8 +47,9 @@ public class SqmTreatedRoot<T, S extends T> extends SqmRoot<S> implements SqmTre
}
@Override
public SqmPathSource<?, S> getReferencedPathSource() {
return (EntityTypeDescriptor<S>) wrappedPath.getReferencedPathSource();
public EntityDomainType<S> getReferencedPathSource() {
//noinspection unchecked
return (EntityDomainType) wrappedPath.getReferencedPathSource();
}
@Override

View File

@ -6,20 +6,20 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.spi.SetPersistentAttribute;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.SetPersistentAttribute;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
*/
public class SqmTreatedSetJoin<O,T, S extends T> extends SqmSetJoin<O,S> implements SqmTreatedPath<T,S> {
private final SqmSetJoin<O,T> wrappedPath;
private final EntityTypeDescriptor<S> treatTarget;
private final EntityDomainType<S> treatTarget;
public SqmTreatedSetJoin(
SqmSetJoin<O,T> wrappedPath,
EntityTypeDescriptor<S> treatTarget,
EntityDomainType<S> treatTarget,
String alias) {
//noinspection unchecked
super(
@ -40,13 +40,23 @@ public class SqmTreatedSetJoin<O,T, S extends T> extends SqmSetJoin<O,S> impleme
}
@Override
public EntityTypeDescriptor<S> getTreatTarget() {
public SetPersistentAttribute<O,S> getModel() {
return super.getModel();
}
@Override
public EntityDomainType<S> getTreatTarget() {
return treatTarget;
}
@Override
@SuppressWarnings("unchecked")
public SqmPathSource<?, S> getReferencedPathSource() {
public SetPersistentAttribute<O,S> getReferencedPathSource() {
return super.getReferencedPathSource();
}
@Override
public JavaTypeDescriptor<S> getJavaTypeDescriptor() {
//noinspection unchecked
return (JavaTypeDescriptor) wrappedPath.getJavaTypeDescriptor();
}
}

View File

@ -6,8 +6,7 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.mapping.spi.EntityValuedNavigable;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
@ -19,17 +18,17 @@ public class SqmTreatedSimplePath<T, S extends T>
extends SqmEntityValuedSimplePath<S>
implements SqmNavigableReference<S>, SqmTreatedPath<T,S> {
private final EntityTypeDescriptor<S> treatTarget;
private final EntityDomainType<S> treatTarget;
private final SqmPath<T> wrappedPath;
@SuppressWarnings("WeakerAccess")
public SqmTreatedSimplePath(
SqmEntityValuedSimplePath<T> wrappedPath,
EntityTypeDescriptor<S> treatTarget,
EntityDomainType<S> treatTarget,
NodeBuilder nodeBuilder) {
//noinspection unchecked
super(
wrappedPath.getNavigablePath(),
(EntityValuedNavigable<S>) wrappedPath.getReferencedPathSource(),
(EntityDomainType<S>) wrappedPath.getReferencedPathSource(),
wrappedPath.getLhs(),
nodeBuilder
);
@ -37,14 +36,14 @@ public class SqmTreatedSimplePath<T, S extends T>
this.wrappedPath = wrappedPath;
}
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "WeakerAccess"})
public SqmTreatedSimplePath(
SqmPluralValuedSimplePath<T> wrappedPath,
EntityTypeDescriptor<S> treatTarget,
EntityDomainType<S> treatTarget,
NodeBuilder nodeBuilder) {
super(
wrappedPath.getNavigablePath(),
wrappedPath.sqmAs( EntityValuedNavigable.class ),
(EntityDomainType<S>) wrappedPath.getReferencedPathSource(),
wrappedPath.getLhs(),
nodeBuilder
);
@ -53,7 +52,7 @@ public class SqmTreatedSimplePath<T, S extends T>
}
@Override
public EntityTypeDescriptor<S> getTreatTarget() {
public EntityDomainType<S> getTreatTarget() {
return treatTarget;
}
@ -64,7 +63,7 @@ public class SqmTreatedSimplePath<T, S extends T>
@Override
public <S1 extends S> SqmTreatedSimplePath<S,S1> treatAs(Class<S1> treatJavaType) throws PathException {
return (SqmTreatedSimplePath<S, S1>) super.treatAs( treatJavaType );
return super.treatAs( treatJavaType );
}
@Override

View File

@ -6,26 +6,26 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.mapping.internal.SingularPersistentAttributeEntity;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
*/
public class SqmTreatedSingularJoin<O,T, S extends T> extends SqmSingularJoin<O,S> implements SqmTreatedPath<T,S> {
private final SqmSingularJoin<O,T> wrappedPath;
private final EntityTypeDescriptor<S> treatTarget;
private final EntityDomainType<S> treatTarget;
public SqmTreatedSingularJoin(
SqmSingularJoin<O,T> wrappedPath,
EntityTypeDescriptor<S> treatTarget,
EntityDomainType<S> treatTarget,
String alias) {
//noinspection unchecked
super(
wrappedPath.getLhs(),
(SingularPersistentAttributeEntity) wrappedPath.getAttribute(),
(SingularPersistentAttribute) wrappedPath.getAttribute(),
alias,
wrappedPath.getSqmJoinType(),
wrappedPath.isFetched(),
@ -41,13 +41,18 @@ public class SqmTreatedSingularJoin<O,T, S extends T> extends SqmSingularJoin<O,
}
@Override
public EntityTypeDescriptor<S> getTreatTarget() {
public EntityDomainType<S> getTreatTarget() {
return treatTarget;
}
@Override
@SuppressWarnings("unchecked")
public SqmPathSource<?, S> getReferencedPathSource() {
return (SingularPersistentAttributeEntity) super.getReferencedPathSource();
public SingularPersistentAttribute getReferencedPathSource() {
return (SingularPersistentAttribute) super.getReferencedPathSource();
}
@Override
public JavaTypeDescriptor<S> getJavaTypeDescriptor() {
return treatTarget.getExpressableJavaTypeDescriptor();
}
}

View File

@ -45,7 +45,7 @@ public class SqmCoalesce<T> extends AbstractSqmExpression<T> implements JpaCoale
return null;
}
return getNodeType().getJavaTypeDescriptor();
return getNodeType().getExpressableJavaTypeDescriptor();
}
public void value(SqmExpression<? extends T> expression) {

View File

@ -6,10 +6,12 @@
*/
package org.hibernate.query.sqm.tree.from;
import org.hibernate.HibernateException;
import org.hibernate.query.criteria.JpaFetch;
import org.hibernate.query.criteria.JpaJoin;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Models a join based on a mapped attribute reference.
@ -21,7 +23,7 @@ public interface SqmAttributeJoin<O,T> extends SqmQualifiedJoin<O,T>, JpaFetch<O
SqmFrom<?,O> getLhs();
@Override
SqmPathSource<?,T> getReferencedPathSource();
SqmPathSource<T> getReferencedPathSource();
@Override
JavaTypeDescriptor<T> getJavaTypeDescriptor();
@ -33,4 +35,13 @@ public interface SqmAttributeJoin<O,T> extends SqmQualifiedJoin<O,T>, JpaFetch<O
void setJoinPredicate(SqmPredicate predicate);
class NotJoinableException extends HibernateException {
public NotJoinableException(String message) {
super( message );
}
public NotJoinableException(String message, Throwable cause) {
super( message, cause );
}
}
}

View File

@ -6,15 +6,14 @@
*/
package org.hibernate.query.sqm.tree.from;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.AbstractSqmFrom;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedCrossJoin;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import static org.hibernate.query.sqm.produce.SqmCreationHelper.buildRootNavigablePath;
@ -25,11 +24,11 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T,T> implements SqmJoin<T,T
private final SqmRoot sqmRoot;
public SqmCrossJoin(
EntityTypeDescriptor<T> joinedEntityDescriptor,
EntityDomainType<T> joinedEntityDescriptor,
String alias,
SqmRoot sqmRoot) {
super(
buildRootNavigablePath( alias, joinedEntityDescriptor.getEntityName() ),
buildRootNavigablePath( alias, joinedEntityDescriptor.getHibernateEntityName() ),
joinedEntityDescriptor,
sqmRoot,
alias,
@ -49,12 +48,12 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T,T> implements SqmJoin<T,T
}
@Override
public SqmPathSource<?, T> getReferencedPathSource() {
return (EntityTypeDescriptor<T>) super.getReferencedPathSource();
public EntityDomainType<T> getReferencedPathSource() {
return (EntityDomainType<T>) super.getReferencedPathSource();
}
public String getEntityName() {
return getReferencedPathSource().getEntityName();
return getReferencedPathSource().getHibernateEntityName();
}
@Override
@ -69,7 +68,7 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T,T> implements SqmJoin<T,T
@Override
public JavaTypeDescriptor<T> getJavaTypeDescriptor() {
return getReferencedPathSource().getJavaTypeDescriptor();
return getReferencedPathSource().getExpressableJavaTypeDescriptor();
}
@Override
@ -83,7 +82,7 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T,T> implements SqmJoin<T,T
@Override
public <S extends T> SqmTreatedCrossJoin<T,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityTypeDescriptor<S> treatTarget = nodeBuilder().getDomainModel().entity( treatJavaType );
final EntityDomainType<S> treatTarget = nodeBuilder().getDomainModel().entity( treatJavaType );
return new SqmTreatedCrossJoin<>( this, null, treatTarget );
}
}

View File

@ -6,9 +6,8 @@
*/
package org.hibernate.query.sqm.tree.from;
import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.SqmCreationHelper;
import org.hibernate.query.sqm.tree.SqmJoinType;
@ -16,7 +15,6 @@ import org.hibernate.query.sqm.tree.domain.AbstractSqmJoin;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedEntityJoin;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.type.descriptor.java.spi.EntityJavaDescriptor;
/**
* @author Steve Ebersole
@ -26,12 +24,12 @@ public class SqmEntityJoin<T> extends AbstractSqmJoin<T,T> implements SqmQualifi
private SqmPredicate joinPredicate;
public SqmEntityJoin(
EntityTypeDescriptor<T> joinedEntityDescriptor,
EntityDomainType<T> joinedEntityDescriptor,
String alias,
SqmJoinType joinType,
SqmRoot sqmRoot) {
super(
SqmCreationHelper.buildRootNavigablePath( joinedEntityDescriptor.getEntityName(), alias ),
SqmCreationHelper.buildRootNavigablePath( joinedEntityDescriptor.getHibernateEntityName(), alias ),
joinedEntityDescriptor,
sqmRoot,
alias,
@ -57,17 +55,12 @@ public class SqmEntityJoin<T> extends AbstractSqmJoin<T,T> implements SqmQualifi
}
@Override
public SqmPathSource<?, T> getReferencedPathSource() {
return (EntityTypeDescriptor<T>) super.getReferencedPathSource();
}
@Override
public EntityJavaDescriptor<T> getJavaTypeDescriptor() {
return getReferencedPathSource().getJavaTypeDescriptor();
public EntityDomainType<T> getReferencedPathSource() {
return (EntityDomainType<T>) super.getReferencedPathSource();
}
public String getEntityName() {
return getReferencedPathSource().getEntityName();
return getReferencedPathSource().getHibernateEntityName();
}
@Override
@ -90,7 +83,7 @@ public class SqmEntityJoin<T> extends AbstractSqmJoin<T,T> implements SqmQualifi
@Override
public <S extends T> SqmTreatedEntityJoin<T,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityTypeDescriptor<S> treatTarget = nodeBuilder().getDomainModel().entity( treatJavaType );
final EntityDomainType<S> treatTarget = nodeBuilder().getDomainModel().entity( treatJavaType );
return new SqmTreatedEntityJoin<>( this, treatTarget, null, getSqmJoinType() );
}
}

View File

@ -19,7 +19,6 @@ import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.metamodel.model.domain.Navigable;
import org.hibernate.query.criteria.JpaFrom;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
@ -44,7 +43,7 @@ public interface SqmFrom<O,T> extends SqmVisitableNode, SqmPath<T>, JpaFrom<O, T
* @return
*/
@Override
SqmPathSource<?, T> getReferencedPathSource();
SqmPathSource<T> getReferencedPathSource();
boolean hasJoins();
@ -65,7 +64,7 @@ public interface SqmFrom<O,T> extends SqmVisitableNode, SqmPath<T>, JpaFrom<O, T
@Override
default void prepareForSubNavigableReference(
Navigable subNavigable,
SqmPathSource subNavigableSource,
boolean isSubReferenceTerminal,
SqmCreationState creationState) {
// nothing to do, already prepared

View File

@ -49,7 +49,7 @@ public class SqmRoot<E> extends AbstractSqmFrom<E,E> implements JpaRoot<E> {
@Override
public JavaTypeDescriptor<E> getJavaTypeDescriptor() {
return getReferencedPathSource().getJavaTypeDescriptor();
return getReferencedPathSource().getExpressableJavaTypeDescriptor();
}
@Override

View File

@ -6,7 +6,7 @@
*/
package org.hibernate.type.descriptor.java;
import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
import org.hibernate.type.descriptor.sql.JdbcTypeJavaClassMappings;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
@ -27,10 +27,15 @@ public interface BasicJavaDescriptor<T> extends JavaTypeDescriptor<T> {
*
* @return The recommended SQL type descriptor
*/
default SqlTypeDescriptor getJdbcRecommendedSqlType(JdbcRecommendedSqlTypeMappingContext context) {
default SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) {
// match legacy behavior
return context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor(
JdbcTypeJavaClassMappings.INSTANCE.determineJdbcTypeCodeForJavaClass( getJavaType() )
);
}
@Override
default T fromString(String string) {
throw new UnsupportedOperationException();
}
}

View File

@ -10,8 +10,10 @@ import java.io.Serializable;
import java.util.Comparator;
import java.util.Objects;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.compare.ComparableComparator;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
/**
* Descriptor for the Java side of a value mapping.
@ -19,16 +21,6 @@ import org.hibernate.type.descriptor.WrapperOptions;
* @author Steve Ebersole
*/
public interface JavaTypeDescriptor<T> extends Serializable {
/**
* Retrieve the Java type handled here.
*
* @return The Java type.
*
* @deprecated Use {@link #getJavaType()} instead
*/
@Deprecated
Class<T> getJavaTypeClass();
/**
* Get the Java type described
*/
@ -45,6 +37,16 @@ public interface JavaTypeDescriptor<T> extends Serializable {
return ImmutableMutabilityPlan.INSTANCE;
}
/**
* Obtain the "recommended" SQL type descriptor for this Java type. The recommended
* aspect comes from the JDBC spec (mostly).
*
* @param context Contextual information
*
* @return The recommended SQL type descriptor
*/
SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context);
/**
* Retrieve the natural comparator for this type.
*/
@ -114,7 +116,7 @@ public interface JavaTypeDescriptor<T> extends Serializable {
*
* @return The unwrapped value.
*/
<X> X unwrap(T value, Class<X> type, WrapperOptions options);
<X> X unwrap(T value, Class<X> type, SharedSessionContractImplementor options);
/**
* Wrap a value as our handled Java type.
@ -127,5 +129,15 @@ public interface JavaTypeDescriptor<T> extends Serializable {
*
* @return The wrapped value.
*/
<X> T wrap(X value, WrapperOptions options);
<X> T wrap(X value, SharedSessionContractImplementor options);
/**
* Retrieve the Java type handled here.
*
* @return The Java type.
*
* @deprecated Use {@link #getJavaType()} instead
*/
@Deprecated
Class<T> getJavaTypeClass();
}

View File

@ -0,0 +1,79 @@
/*
* 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.type.descriptor.java.spi;
import org.hibernate.collection.spi.CollectionSemantics;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
/**
* Extension of the general JavaTypeDescriptor for "collection types"
*
* @apiNote "Collection types" are defined loosely here to cover mapping
* collection types other than those from the "Java Collection Framework".
*
* @see CollectionSemantics
*
* @author Steve Ebersole
*/
public class CollectionJavaTypeDescriptor<C> extends AbstractTypeDescriptor<C> {
private final CollectionSemantics<C> semantics;
@SuppressWarnings("unchecked")
public CollectionJavaTypeDescriptor(Class<? extends C> type, CollectionSemantics<C> semantics) {
super( (Class) type );
this.semantics = semantics;
}
public CollectionSemantics<C> getSemantics() {
return semantics;
}
@Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) {
// none
return null;
}
@Override
public C fromString(String string) {
throw new UnsupportedOperationException( );
}
@Override
public <X> X unwrap(C value, Class<X> type, SharedSessionContractImplementor session) {
throw new UnsupportedOperationException( );
}
@Override
public <X> C wrap(X value, SharedSessionContractImplementor session) {
throw new UnsupportedOperationException( );
}
@Override
public boolean areEqual(C one, C another) {
return one == another ||
(
one instanceof PersistentCollection &&
( (PersistentCollection) one ).wasInitialized() &&
( (PersistentCollection) one ).isWrapper( another )
) ||
(
another instanceof PersistentCollection &&
( (PersistentCollection) another ).wasInitialized() &&
( (PersistentCollection) another ).isWrapper( one )
);
}
@Override
public int extractHashCode(C x) {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,99 @@
/*
* 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.type.descriptor.java.spi;
import java.sql.Types;
import javax.persistence.EnumType;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
/**
* Describes a Java Enum type.
*
* @author Steve Ebersole
*/
public class EnumJavaDescriptor<E extends Enum> extends AbstractTypeDescriptor<E> {
@SuppressWarnings("unchecked")
public EnumJavaDescriptor(Class<E> type) {
super( type, ImmutableMutabilityPlan.INSTANCE );
}
@Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) {
if ( context.getEnumeratedType() != null && context.getEnumeratedType() == EnumType.STRING ) {
return context.isNationalized()
? context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor( Types.NVARCHAR )
: context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor( Types.VARCHAR );
}
else {
return context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor( Types.INTEGER );
}
}
@Override
public String toString(E value) {
return value == null ? "<null>" : value.name();
}
@Override
@SuppressWarnings("unchecked")
public E fromString(String string) {
return string == null ? null : (E) Enum.valueOf( getJavaType(), string );
}
@Override
@SuppressWarnings("unchecked")
public <X> X unwrap(E value, Class<X> type, SharedSessionContractImplementor session) {
return (X) value;
}
@Override
@SuppressWarnings("unchecked")
public <X> E wrap(X value, SharedSessionContractImplementor session) {
return (E) value;
}
public Integer toOrdinal(E domainForm) {
if ( domainForm == null ) {
return null;
}
return domainForm.ordinal();
}
@SuppressWarnings("unchecked")
public E fromOrdinal(Integer relationalForm) {
if ( relationalForm == null ) {
return null;
}
return (E) getJavaType().getEnumConstants()[ relationalForm ];
}
@SuppressWarnings("unchecked")
public E fromName(String relationalForm) {
if ( relationalForm == null ) {
return null;
}
return (E) Enum.valueOf( getJavaType(), relationalForm );
}
public String toName(E domainForm) {
if ( domainForm == null ) {
return null;
}
return domainForm.name();
}
@Override
public String toString() {
return getClass().getSimpleName() + "(" + getJavaType().getName() + ")";
}
}

View File

@ -0,0 +1,148 @@
/*
* 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.type.descriptor.java.spi;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import org.hibernate.collection.internal.StandardArraySemantics;
import org.hibernate.collection.internal.StandardBagSemantics;
import org.hibernate.collection.internal.StandardListSemantics;
import org.hibernate.collection.internal.StandardMapSemantics;
import org.hibernate.collection.internal.StandardOrderedMapSemantics;
import org.hibernate.collection.internal.StandardOrderedSetSemantics;
import org.hibernate.collection.internal.StandardSetSemantics;
import org.hibernate.collection.internal.StandardSortedMapSemantics;
import org.hibernate.collection.internal.StandardSortedSetSemantics;
import org.hibernate.type.descriptor.java.BigDecimalTypeDescriptor;
import org.hibernate.type.descriptor.java.BigIntegerTypeDescriptor;
import org.hibernate.type.descriptor.java.BlobTypeDescriptor;
import org.hibernate.type.descriptor.java.BooleanTypeDescriptor;
import org.hibernate.type.descriptor.java.ByteArrayTypeDescriptor;
import org.hibernate.type.descriptor.java.ByteTypeDescriptor;
import org.hibernate.type.descriptor.java.CalendarTypeDescriptor;
import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor;
import org.hibernate.type.descriptor.java.CharacterTypeDescriptor;
import org.hibernate.type.descriptor.java.ClassTypeDescriptor;
import org.hibernate.type.descriptor.java.ClobTypeDescriptor;
import org.hibernate.type.descriptor.java.CurrencyTypeDescriptor;
import org.hibernate.type.descriptor.java.DateTypeDescriptor;
import org.hibernate.type.descriptor.java.DoubleTypeDescriptor;
import org.hibernate.type.descriptor.java.DurationJavaDescriptor;
import org.hibernate.type.descriptor.java.FloatTypeDescriptor;
import org.hibernate.type.descriptor.java.InstantJavaDescriptor;
import org.hibernate.type.descriptor.java.IntegerTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JdbcDateTypeDescriptor;
import org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor;
import org.hibernate.type.descriptor.java.LocalDateJavaDescriptor;
import org.hibernate.type.descriptor.java.LocalDateTimeJavaDescriptor;
import org.hibernate.type.descriptor.java.LocaleTypeDescriptor;
import org.hibernate.type.descriptor.java.LongTypeDescriptor;
import org.hibernate.type.descriptor.java.NClobTypeDescriptor;
import org.hibernate.type.descriptor.java.OffsetDateTimeJavaDescriptor;
import org.hibernate.type.descriptor.java.OffsetTimeJavaDescriptor;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
import org.hibernate.type.descriptor.java.PrimitiveCharacterArrayTypeDescriptor;
import org.hibernate.type.descriptor.java.ShortTypeDescriptor;
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
import org.hibernate.type.descriptor.java.TimeZoneTypeDescriptor;
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
import org.hibernate.type.descriptor.java.UrlTypeDescriptor;
import org.hibernate.type.descriptor.java.ZonedDateTimeJavaDescriptor;
/**
*
* @author Steve Ebersole
*/
public class JavaTypeDescriptorBaseline {
public interface BaselineTarget {
void addBaselineDescriptor(JavaTypeDescriptor descriptor);
void addBaselineDescriptor(Class describedJavaType, JavaTypeDescriptor descriptor);
}
@SuppressWarnings("unchecked")
public static void prime(BaselineTarget target) {
primePrimitive( target, ByteTypeDescriptor.INSTANCE );
primePrimitive( target, BooleanTypeDescriptor.INSTANCE );
primePrimitive( target, CharacterTypeDescriptor.INSTANCE );
primePrimitive( target, ShortTypeDescriptor.INSTANCE );
primePrimitive( target, IntegerTypeDescriptor.INSTANCE );
primePrimitive( target, LongTypeDescriptor.INSTANCE );
primePrimitive( target, FloatTypeDescriptor.INSTANCE );
primePrimitive( target, DoubleTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( BigDecimalTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( BigIntegerTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( StringTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( BlobTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( ClobTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( NClobTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( ByteArrayTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( CharacterArrayTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( PrimitiveByteArrayTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( PrimitiveCharacterArrayTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( DurationJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( InstantJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( LocalDateJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( LocalDateTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( OffsetDateTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( OffsetTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( ZonedDateTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( CalendarTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( DateTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( java.sql.Date.class, JdbcDateTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( java.sql.Time.class, JdbcTimestampTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( java.sql.Timestamp.class, JdbcTimestampTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( TimeZoneTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( ClassTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( CurrencyTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( LocaleTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( UrlTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( UUIDTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( Collection.class, StandardBagSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( Object[].class, StandardArraySemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( List.class, StandardListSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( ArrayList.class, StandardListSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( Set.class, StandardSetSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( HashSet.class, StandardSetSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( SortedSet.class, StandardSortedSetSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( TreeSet.class, StandardOrderedSetSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( LinkedHashSet.class, StandardOrderedSetSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( Map.class, StandardMapSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( HashMap.class, StandardMapSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( SortedMap.class, StandardSortedMapSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( TreeMap.class, StandardSortedMapSemantics.INSTANCE ) );
target.addBaselineDescriptor( new CollectionJavaTypeDescriptor( LinkedHashMap.class, StandardOrderedMapSemantics.INSTANCE ) );
target.addBaselineDescriptor( MapEntryJavaDescriptor.INSTANCE );
}
private static void primePrimitive(BaselineTarget target, JavaTypeDescriptor descriptor) {
target.addBaselineDescriptor( descriptor );
target.addBaselineDescriptor( ( (Primitive) descriptor ).getPrimitiveClass(), descriptor );
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.type.descriptor.java.spi;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
/**
* AbstractBasicTypeDescriptor adapter for cases where we do not know a proper JavaTypeDescriptor
* for a given Java type.
*
* @author Steve Ebersole
*/
public class JavaTypeDescriptorBasicAdaptor<T> extends AbstractTypeDescriptor<T> {
public JavaTypeDescriptorBasicAdaptor(Class<T> type) {
super( type );
}
@Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) {
throw new UnsupportedOperationException(
"Recommended SqlTypeDescriptor not known for this Java type : " + getJavaType().getName()
);
}
@Override
public String toString(T value) {
return value.toString();
}
@Override
public T fromString(String string) {
throw new UnsupportedOperationException(
"Conversion from String strategy not known for this Java type : " + getJavaType().getName()
);
}
@Override
public <X> X unwrap(T value, Class<X> type, SharedSessionContractImplementor session) {
throw new UnsupportedOperationException(
"Unwrap strategy not known for this Java type : " + getJavaType().getName()
);
}
@Override
public <X> T wrap(X value, SharedSessionContractImplementor session) {
throw new UnsupportedOperationException(
"Wrap strategy not known for this Java type : " + getJavaType().getName()
);
}
}

View File

@ -8,9 +8,18 @@ package org.hibernate.type.descriptor.java.spi;
import java.io.Serializable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import org.hibernate.boot.model.TypeContributor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.SerializationHelper;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
import org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.type.spi.TypeConfigurationAware;
import org.jboss.logging.Logger;
@ -22,16 +31,46 @@ import org.jboss.logging.Logger;
*
* @since 5.3
*/
public class JavaTypeDescriptorRegistry implements Serializable {
public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.BaselineTarget, Serializable {
private static final Logger log = Logger.getLogger( JavaTypeDescriptorRegistry.class );
private final TypeConfiguration typeConfiguration;
private ConcurrentHashMap<Class, JavaTypeDescriptor> descriptorsByClass = new ConcurrentHashMap<>();
@SuppressWarnings("unused")
public JavaTypeDescriptorRegistry(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// baseline descriptors
@Override
public void addBaselineDescriptor(JavaTypeDescriptor descriptor) {
if ( descriptor.getJavaType() == null ) {
throw new IllegalStateException( "Illegal to add BasicJavaTypeDescriptor with null Java type" );
}
addBaselineDescriptor( descriptor.getJavaType(), descriptor );
}
@Override
public void addBaselineDescriptor(Class describedJavaType, JavaTypeDescriptor descriptor) {
performInjections( descriptor );
descriptorsByClass.put( describedJavaType, descriptor );
}
private void performInjections(JavaTypeDescriptor descriptor) {
if ( descriptor instanceof TypeConfigurationAware ) {
// would be nice to make the JavaTypeDescriptor for an entity, e.g., aware of the the TypeConfiguration
( (TypeConfigurationAware) descriptor ).setTypeConfiguration( typeConfiguration );
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// descriptor access
public <T> JavaTypeDescriptor<T> getDescriptor(Class<T> javaType) {
return RegistryHelper.INSTANCE.resolveDescriptor(
descriptorsByClass,
@ -58,5 +97,102 @@ public class JavaTypeDescriptorRegistry implements Serializable {
old
);
}
performInjections( descriptor );
}
public <J> JavaTypeDescriptor<J> resolveDescriptor(Class<J> javaType, Supplier<JavaTypeDescriptor<J>> creator) {
//noinspection unchecked
return descriptorsByClass.computeIfAbsent(
javaType,
jt -> {
final JavaTypeDescriptor<J> jtd = creator.get();
performInjections( jtd );
return jtd;
}
);
}
@SuppressWarnings("unchecked")
public <J> JavaTypeDescriptor<J> resolveDescriptor(Class<J> javaType) {
return resolveDescriptor(
javaType,
() -> {
// the fallback will always be a basic type
final JavaTypeDescriptor<J> fallbackDescriptor;
if ( javaType.isEnum() ) {
fallbackDescriptor = new EnumJavaDescriptor( javaType );
}
else if ( Serializable.class.isAssignableFrom( javaType ) ) {
fallbackDescriptor = new OnTheFlySerializableJavaDescriptor( javaType );
}
else {
fallbackDescriptor = new JavaTypeDescriptorBasicAdaptor( javaType );
}
return fallbackDescriptor;
}
);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private class OnTheFlySerializableJavaDescriptor<T extends Serializable> extends AbstractTypeDescriptor<T> {
private final SqlTypeDescriptor sqlTypeDescriptor;
public OnTheFlySerializableJavaDescriptor(Class<T> type) {
super( type );
// todo (6.0) : would be nice to expose for config by user
// todo (6.0) : ^^ might also be nice to allow them to plug in a "JavaTypeDescriptorResolver"
// - that allows them to hook into the #getDescriptor call either as the primary or as a fallback
log.debugf(
"Could not find matching JavaTypeDescriptor for requested Java class [%s]; using fallback via its Serializable interface. " +
"This means Hibernate does not know how to perform certain basic operations in relation to this Java type" +
"which can lead to those operations having a large performance impact. Consider registering these " +
"JavaTypeDescriptors with the %s during bootstrap, either directly or through a registered %s " +
"accessing the %s ",
getJavaType().getName(),
JavaTypeDescriptorRegistry.class.getName(),
TypeContributor.class.getName(),
TypeConfiguration.class.getName()
);
sqlTypeDescriptor = VarbinaryTypeDescriptor.INSTANCE;
}
@Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) {
return sqlTypeDescriptor;
}
@Override
public <X> X unwrap(T value, Class<X> type, SharedSessionContractImplementor session) {
if ( type.equals( byte[].class ) ) {
throw new UnsupportedOperationException( "Cannot unwrap Serializable to format other than byte[]" );
}
return (X) SerializationHelper.serialize( value );
}
@Override
@SuppressWarnings("unchecked")
public <X> T wrap(X value, SharedSessionContractImplementor session) {
if ( value == null ) {
return null;
}
if ( value.getClass().equals( byte[].class ) ) {
throw new UnsupportedOperationException( "Cannot unwrap Serializable to format other than byte[]" );
}
final byte[] bytes = (byte[]) value;
return (T) SerializationHelper.deserialize( bytes );
}
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.type.descriptor.java.spi;
import java.io.Serializable;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Additional contract for primitive / primitive wrapper Java types.
*
* @author Steve Ebersole
*/
public interface Primitive<J extends Serializable> extends JavaTypeDescriptor<J> {
/**
* Retrieve the primitive counterpart to the wrapper type identified by
* this descriptor
*
* @return The primitive Java type.
*/
Class getPrimitiveClass();
/**`
* Get this Java type's default value.
*
* @return The default value.
*/
J getDefaultValue();
}

View File

@ -6,13 +6,11 @@
*/
package org.hibernate.type.descriptor.java.spi;
import java.io.Serializable;
import java.util.Map;
import java.util.function.Supplier;
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.SerializableTypeDescriptor;
import org.jboss.logging.Logger;

View File

@ -4,7 +4,7 @@
* 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.type.descriptor.spi;
package org.hibernate.type.descriptor.sql;
import java.sql.Types;
import javax.persistence.EnumType;
@ -19,7 +19,7 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @author Steve Ebersole
*/
public interface JdbcRecommendedSqlTypeMappingContext {
public interface SqlTypeDescriptorIndicators {
/**
* Was nationalized character datatype requested for the given Java type?
*

View File

@ -9,10 +9,9 @@ package org.hibernate.test.converter.custom;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.java.MutableMutabilityPlan;
import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
@ -40,7 +39,7 @@ public class MyCustomJavaTypeDescriptor implements BasicJavaDescriptor<MyCustomJ
}
@Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(JdbcRecommendedSqlTypeMappingContext context) {
public SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) {
return MyCustomSqlTypeDescriptor.INSTANCE;
}

View File

@ -11,7 +11,7 @@ import java.sql.Types;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.geolatte.geom.Geometry;
@ -39,7 +39,7 @@ public class GeolatteGeometryJavaTypeDescriptor extends AbstractTypeDescriptor<G
}
@Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(JdbcRecommendedSqlTypeMappingContext context) {
public SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) {
return context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor( Types.ARRAY );
}