6 - SQM based on JPA type system
This commit is contained in:
parent
3958e37103
commit
af2c32e32c
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
}
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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(
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -15,5 +15,5 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SqmExpressable<J> {
|
||||
JavaTypeDescriptor<J> getJavaTypeDescriptor();
|
||||
JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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" );
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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() + ")";
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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?
|
||||
*
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue