HHH-15323 @AnyDiscriminator Unable to filter a polymorphic relationship in a query
This commit is contained in:
parent
c84b36e3e9
commit
83ea2e8f42
|
@ -20,6 +20,7 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
|
@ -98,6 +99,14 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
|
|||
return discriminatorMapping.resolveDiscriminatorValueToEntityMapping( entityMappingType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelectable(int offset, SelectableConsumer consumer) {
|
||||
discriminatorMapping.getDiscriminatorPart().forEachSelectable( offset, consumer );
|
||||
discriminatorMapping.getKeyPart().forEachSelectable( offset + 1, consumer );
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFetchableName() {
|
||||
return nature.getName();
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.UnsupportedMappingException;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.query.PathException;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||
import org.hibernate.query.sqm.tree.domain.AbstractSqmPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
|
||||
public class AnyDiscriminatorSqmPath extends AbstractSqmPath {
|
||||
|
||||
protected AnyDiscriminatorSqmPath(
|
||||
NavigablePath navigablePath,
|
||||
SqmPathSource referencedPathSource,
|
||||
SqmPath lhs,
|
||||
NodeBuilder nodeBuilder) {
|
||||
super( navigablePath, referencedPathSource, lhs, nodeBuilder );
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnyDiscriminatorSqmPath copy(SqmCopyContext context) {
|
||||
final AnyDiscriminatorSqmPath existing = context.getCopy( this );
|
||||
if ( existing != null ) {
|
||||
return existing;
|
||||
}
|
||||
return context.registerCopy(
|
||||
this,
|
||||
(AnyDiscriminatorSqmPath) getLhs().copy( context ).type()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitAnyDiscriminatorTypeExpression( this ) ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "type(" );
|
||||
getLhs().appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<?> resolvePathPart(String name, boolean isTerminal, SqmCreationState creationState) {
|
||||
throw new IllegalStateException( "Discriminator cannot be de-referenced" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmTreatedPath treatAs(Class treatJavaType) throws PathException {
|
||||
throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmTreatedPath treatAs(EntityDomainType treatTarget) throws PathException {
|
||||
throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.AnyMappingDomainType;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
|
||||
/**
|
||||
* SqmPathSource implementation for {@link org.hibernate.annotations.AnyDiscriminator}
|
||||
*
|
||||
*/
|
||||
public class AnyDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
|
||||
implements BindableType<D>, ReturnableType<D> {
|
||||
|
||||
|
||||
public AnyDiscriminatorSqmPathSource(
|
||||
String localPathName,
|
||||
SimpleDomainType domainType,
|
||||
BindableType jpaBindableType) {
|
||||
super( localPathName, domainType, jpaBindableType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<D> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
|
||||
final NavigablePath navigablePath;
|
||||
if ( intermediatePathSource == null ) {
|
||||
navigablePath = lhs.getNavigablePath();
|
||||
}
|
||||
else {
|
||||
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() );
|
||||
}
|
||||
return new AnyDiscriminatorSqmPath( navigablePath, this, lhs, lhs.nodeBuilder() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPathSource<?> findSubPathSource(String name) {
|
||||
throw new IllegalStateException( "Entity discriminator cannot be de-referenced" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceType getPersistenceType() {
|
||||
return PersistenceType.BASIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<D> getJavaType() {
|
||||
return getExpressibleJavaType().getJavaTypeClass();
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
|
|||
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
||||
import org.hibernate.type.AnyType;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.MetaType;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
/**
|
||||
|
@ -41,7 +42,7 @@ public class AnyMappingDomainTypeImpl<T> implements AnyMappingDomainType<T> {
|
|||
|
||||
@Override
|
||||
public SimpleDomainType<?> getDiscriminatorType() {
|
||||
return (BasicType<?>) anyType.getDiscriminatorType();
|
||||
return (SimpleDomainType<?>) ((MetaType) anyType.getDiscriminatorType()).getBaseType();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,6 +22,7 @@ import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRI
|
|||
*/
|
||||
public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> implements BindableType<J> {
|
||||
private final SqmPathSource<?> keyPathSource;
|
||||
private final AnyDiscriminatorSqmPathSource discriminatorPathSource;
|
||||
|
||||
public AnyMappingSqmPathSource(
|
||||
String localPathName,
|
||||
|
@ -29,6 +30,7 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> impleme
|
|||
BindableType jpaBindableType) {
|
||||
super( localPathName, domainType, jpaBindableType );
|
||||
keyPathSource = new BasicSqmPathSource<>( "id", (BasicDomainType<?>) domainType.getKeyType(), SINGULAR_ATTRIBUTE );
|
||||
discriminatorPathSource = new AnyDiscriminatorSqmPathSource<>( localPathName, domainType.getDiscriminatorType(), jpaBindableType );
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("unchecked")
|
||||
|
@ -41,6 +43,9 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> impleme
|
|||
if ( "id".equals( name ) ) {
|
||||
return keyPathSource;
|
||||
}
|
||||
else if("{discriminator}".equals( name )) {
|
||||
return discriminatorPathSource;
|
||||
}
|
||||
|
||||
throw new UnsupportedMappingException( "De-referencing parts of an ANY mapping, other than the key, is not supported" );
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
|||
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
|
||||
import org.hibernate.metamodel.model.domain.internal.EntitySqmPathSource;
|
||||
import org.hibernate.query.PathException;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
|
@ -118,6 +119,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
|||
import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAliasedNodeRef;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAny;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAnyDiscriminatorValue;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmByUnit;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
||||
|
@ -133,6 +135,7 @@ import org.hibernate.query.sqm.tree.expression.SqmExtractUnit;
|
|||
import org.hibernate.query.sqm.tree.expression.SqmFormat;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralNull;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmOver;
|
||||
|
@ -2101,8 +2104,21 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
);
|
||||
break;
|
||||
}
|
||||
left = (SqmExpression<?>) leftExpressionContext.accept( this );
|
||||
right = (SqmExpression<?>) rightExpressionContext.accept( this );
|
||||
final SqmExpression<?> l = (SqmExpression<?>) leftExpressionContext.accept( this );
|
||||
final SqmExpression<?> r = (SqmExpression<?>) rightExpressionContext.accept( this );
|
||||
if ( l instanceof AnyDiscriminatorSqmPath && r instanceof SqmLiteralEntityType ) {
|
||||
left = l;
|
||||
right = createDiscriminatorValue( (AnyDiscriminatorSqmPath) left, rightExpressionContext );
|
||||
}
|
||||
else if ( r instanceof AnyDiscriminatorSqmPath && l instanceof SqmLiteralEntityType ) {
|
||||
left = createDiscriminatorValue( (AnyDiscriminatorSqmPath) r, leftExpressionContext );
|
||||
right = r;
|
||||
}
|
||||
else {
|
||||
left = l;
|
||||
right = r;
|
||||
}
|
||||
|
||||
// This is something that we used to support before 6 which is also used in our testsuite
|
||||
if ( left instanceof SqmLiteralNull<?> ) {
|
||||
return new SqmNullnessPredicate(
|
||||
|
@ -2136,6 +2152,20 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
);
|
||||
}
|
||||
|
||||
private <T> SqmExpression<T> createDiscriminatorValue(AnyDiscriminatorSqmPath anyDiscriminatorTypeSqmPath, HqlParser.ExpressionContext valueExpressionContext) {
|
||||
final SqmPath<T> discriminatorSqmPath = anyDiscriminatorTypeSqmPath.getLhs();
|
||||
final EntityDomainType<T> entityWithDiscriminator = creationContext.getJpaMetamodel()
|
||||
.entity( discriminatorSqmPath.findRoot().getNavigablePath().getLocalName() );
|
||||
final EntityDomainType<Object> entityDiscriminatorValue = creationContext.getJpaMetamodel()
|
||||
.resolveHqlEntityReference( valueExpressionContext.getText() );
|
||||
return new SqmAnyDiscriminatorValue<>(
|
||||
entityWithDiscriminator,
|
||||
discriminatorSqmPath.getNodeType().getPathName(),
|
||||
entityDiscriminatorValue,
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
}
|
||||
|
||||
private SqmExpression<?> resolveEnumShorthandLiteral(HqlParser.ExpressionContext expressionContext, Map<Class<?>, Enum<?>> possibleEnumValues, Class<?> enumType) {
|
||||
final Enum<?> enumValue;
|
||||
if ( possibleEnumValues != null && ( enumValue = possibleEnumValues.get( enumType ) ) != null ) {
|
||||
|
@ -3335,7 +3365,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
//noinspection unchecked
|
||||
return new SqmLiteral<>(
|
||||
value,
|
||||
(SqmExpressible<Number>) type,
|
||||
type,
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.query.sqm;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
|
||||
import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath;
|
||||
import org.hibernate.query.sqm.tree.cte.SqmCteContainer;
|
||||
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
|
||||
|
@ -29,6 +30,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
|||
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
||||
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAny;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAnyDiscriminatorValue;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmByUnit;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
||||
|
@ -227,6 +229,10 @@ public interface SemanticQueryWalker<T> {
|
|||
|
||||
T visitEntityTypeLiteralExpression(SqmLiteralEntityType<?> expression);
|
||||
|
||||
T visitAnyDiscriminatorTypeExpression(AnyDiscriminatorSqmPath expression);
|
||||
|
||||
T visitAnyDiscriminatorTypeValueExpression(SqmAnyDiscriminatorValue expression);
|
||||
|
||||
T visitParameterizedEntityTypeExpression(SqmParameterizedEntityType<?> expression);
|
||||
|
||||
T visitUnaryOperationExpression(SqmUnaryOperation<?> expression);
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.query.sqm.internal;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
|
||||
import org.hibernate.query.QueryLogging;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath;
|
||||
|
@ -33,6 +34,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
|||
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
||||
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAny;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAnyDiscriminatorValue;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmByUnit;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
||||
|
@ -1044,6 +1046,16 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitAnyDiscriminatorTypeExpression(AnyDiscriminatorSqmPath expression) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitAnyDiscriminatorTypeValueExpression(SqmAnyDiscriminatorValue expression) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDynamicInstantiation(SqmDynamicInstantiation sqmDynamicInstantiation) {
|
||||
processStanza(
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.query.sqm.spi;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.sql.internal.SelfInterpretingSqmPath;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
|
@ -34,6 +35,7 @@ import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
|||
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAggregateFunction;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAny;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAnyDiscriminatorValue;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmByUnit;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
||||
|
@ -578,6 +580,16 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
|
|||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitAnyDiscriminatorTypeExpression(AnyDiscriminatorSqmPath expression) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitAnyDiscriminatorTypeValueExpression(SqmAnyDiscriminatorValue expression) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitParameterizedEntityTypeExpression(SqmParameterizedEntityType<?> expression) {
|
||||
expression.getDiscriminatorSource().accept( this );
|
||||
|
|
|
@ -63,6 +63,7 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
|||
import org.hibernate.metamodel.mapping.Bindable;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.ConvertibleModelPart;
|
||||
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
|
||||
|
@ -83,6 +84,7 @@ import org.hibernate.metamodel.mapping.SelectableMappings;
|
|||
import org.hibernate.metamodel.mapping.SqlExpressible;
|
||||
import org.hibernate.metamodel.mapping.SqlTypedMapping;
|
||||
import org.hibernate.metamodel.mapping.ValueMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
|
||||
import org.hibernate.metamodel.mapping.internal.SqlTypedMappingImpl;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
|
@ -96,6 +98,7 @@ import org.hibernate.metamodel.model.domain.EntityDomainType;
|
|||
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
||||
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
|
||||
import org.hibernate.query.derived.AnonymousTupleTableGroupProducer;
|
||||
import org.hibernate.query.derived.AnonymousTupleType;
|
||||
import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource;
|
||||
|
@ -138,6 +141,7 @@ import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
|||
import org.hibernate.query.sqm.spi.BaseSemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.sql.internal.BasicValuedPathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.DiscriminatedAssociationPathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.DiscriminatedAssociationTypePathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
||||
import org.hibernate.query.sqm.sql.internal.EmbeddableValuedPathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.EntityValuedPathInterpretation;
|
||||
|
@ -182,6 +186,7 @@ import org.hibernate.query.sqm.tree.expression.Conversion;
|
|||
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAliasedNodeRef;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAny;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAnyDiscriminatorValue;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmByUnit;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
||||
|
@ -6227,6 +6232,60 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
return new EntityTypeLiteral( mappingDescriptor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitAnyDiscriminatorTypeExpression(AnyDiscriminatorSqmPath expression) {
|
||||
return DiscriminatedAssociationTypePathInterpretation.from( expression, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitAnyDiscriminatorTypeValueExpression(SqmAnyDiscriminatorValue expression) {
|
||||
final EntityPersister mappingDescriptor = creationContext.getSessionFactory()
|
||||
.getRuntimeMetamodels()
|
||||
.getMappingMetamodel()
|
||||
.getEntityDescriptor( ((EntityDomainType)expression.getNodeType()).getHibernateEntityName() );
|
||||
for ( AttributeMapping attributeMapping : mappingDescriptor.getAttributeMappings() ) {
|
||||
if ( attributeMapping instanceof EmbeddedAttributeMapping ) {
|
||||
final ModelPart subPart = ( (EmbeddedAttributeMapping) attributeMapping ).findSubPart(
|
||||
expression.getPathName(),
|
||||
null
|
||||
);
|
||||
if ( subPart != null ) {
|
||||
return buildQueryLiteral( expression, subPart );
|
||||
}
|
||||
}
|
||||
else if ( attributeMapping.getAttributeName().equals( expression.getPathName() ) ) {
|
||||
return buildQueryLiteral( expression, attributeMapping );
|
||||
}
|
||||
}
|
||||
throw new HibernateException(String.format(
|
||||
Locale.ROOT,
|
||||
"Could not locate attribute mapping : %s -> %s",
|
||||
mappingDescriptor.getEntityName(),
|
||||
expression.getPathName()
|
||||
));
|
||||
}
|
||||
|
||||
private QueryLiteral<Object> buildQueryLiteral(
|
||||
SqmAnyDiscriminatorValue expression,
|
||||
ModelPart attributeMapping) {
|
||||
final DiscriminatedAssociationModelPart discriminatedAssociationModelPart;
|
||||
if ( attributeMapping instanceof PluralAttributeMapping ) {
|
||||
discriminatedAssociationModelPart = (DiscriminatedAssociationModelPart) ( (PluralAttributeMapping) attributeMapping ).getElementDescriptor();
|
||||
}
|
||||
else {
|
||||
assert attributeMapping instanceof DiscriminatedAssociationModelPart;
|
||||
discriminatedAssociationModelPart = (DiscriminatedAssociationModelPart) attributeMapping;
|
||||
}
|
||||
final Object value = discriminatedAssociationModelPart.resolveDiscriminatorForEntityType(
|
||||
creationContext.getMappingMetamodel()
|
||||
.findEntityDescriptor( expression.getEntityValue().getHibernateEntityName() ) );
|
||||
|
||||
return new QueryLiteral<>(
|
||||
value,
|
||||
discriminatedAssociationModelPart.getDiscriminatorPart()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitParameterizedEntityTypeExpression(SqmParameterizedEntityType<?> sqmExpression) {
|
||||
assert resolveInferredType() instanceof EntityDiscriminatorMapping;
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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.query.sqm.sql.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart;
|
||||
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.ast.SqlAstWalker;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
|
||||
public class DiscriminatedAssociationTypePathInterpretation<T> extends AbstractSqmPathInterpretation<T> {
|
||||
|
||||
private final Expression expression;
|
||||
|
||||
public static <T> DiscriminatedAssociationTypePathInterpretation<T> from(
|
||||
AnyDiscriminatorSqmPath sqmPath,
|
||||
SqmToSqlAstConverter converter) {
|
||||
final SqmPath lhs = sqmPath.getLhs();
|
||||
final TableGroup tableGroup = converter.getFromClauseAccess().findTableGroup( lhs.getLhs().getNavigablePath() );
|
||||
final ModelPart subPart = tableGroup.getModelPart().findSubPart(
|
||||
lhs.getNavigablePath().getLocalName(),
|
||||
null
|
||||
);
|
||||
|
||||
final DiscriminatedAssociationModelPart mapping;
|
||||
if ( subPart instanceof PluralAttributeMapping ) {
|
||||
PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) subPart;
|
||||
mapping = (DiscriminatedAssociationModelPart) pluralAttributeMapping.getElementDescriptor();
|
||||
}
|
||||
else {
|
||||
mapping = (DiscriminatedAssociationModelPart) subPart;
|
||||
}
|
||||
|
||||
final List<Expression> tupleExpressions = new ArrayList<>();
|
||||
|
||||
mapping.forEachSelectable(
|
||||
(selectionIndex, selectableMapping) -> {
|
||||
if ( selectableMapping instanceof AnyDiscriminatorPart ) {
|
||||
final TableReference tableReference = tableGroup.getPrimaryTableReference();
|
||||
final Expression expression = converter.getSqlExpressionResolver().resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
selectableMapping.getSelectionExpression()
|
||||
),
|
||||
processingState -> new ColumnReference(
|
||||
tableReference,
|
||||
selectableMapping,
|
||||
converter.getCreationContext().getSessionFactory()
|
||||
)
|
||||
);
|
||||
tupleExpressions.add( expression );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
assert tupleExpressions.size() == 1;
|
||||
|
||||
return new DiscriminatedAssociationTypePathInterpretation<T>(
|
||||
sqmPath.getNavigablePath(),
|
||||
mapping,
|
||||
tableGroup,
|
||||
tupleExpressions.get( 0 )
|
||||
);
|
||||
}
|
||||
|
||||
public DiscriminatedAssociationTypePathInterpretation(
|
||||
NavigablePath navigablePath,
|
||||
ModelPart mapping,
|
||||
TableGroup tableGroup,
|
||||
Expression expression) {
|
||||
super( navigablePath, mapping, tableGroup );
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(SqlAstWalker sqlTreeWalker) {
|
||||
expression.accept( sqlTreeWalker );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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.query.sqm.tree.expression;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.query.hql.HqlInterpretationException;
|
||||
import org.hibernate.query.hql.spi.SemanticPathPart;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||
|
||||
public class SqmAnyDiscriminatorValue<T> extends AbstractSqmExpression<T>
|
||||
implements SqmSelectableNode<T>, SemanticPathPart {
|
||||
|
||||
private final EntityDomainType value;
|
||||
private final String pathName;
|
||||
|
||||
public SqmAnyDiscriminatorValue(
|
||||
EntityDomainType<T> entityWithDiscriminator,
|
||||
String pathName,
|
||||
EntityDomainType entityValue,
|
||||
NodeBuilder nodeBuilder) {
|
||||
super( entityWithDiscriminator, nodeBuilder );
|
||||
this.value = entityValue;
|
||||
this.pathName = pathName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmAnyDiscriminatorValue<T> copy(SqmCopyContext context) {
|
||||
final SqmAnyDiscriminatorValue<T> existing = context.getCopy( this );
|
||||
if ( existing != null ) {
|
||||
return existing;
|
||||
}
|
||||
final SqmAnyDiscriminatorValue<T> expression = context.registerCopy(
|
||||
this,
|
||||
new SqmAnyDiscriminatorValue<>(
|
||||
(EntityDomainType) getNodeType(),
|
||||
pathName,
|
||||
value,
|
||||
nodeBuilder()
|
||||
)
|
||||
);
|
||||
copyTo( expression, context );
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitAnyDiscriminatorTypeValueExpression( this );
|
||||
}
|
||||
|
||||
public EntityDomainType getEntityValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getPathName() {
|
||||
return pathName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asLoggableText() {
|
||||
return getEntityValue().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SemanticPathPart resolvePathPart(
|
||||
String name,
|
||||
boolean isTerminal,
|
||||
SqmCreationState creationState) {
|
||||
throw new HqlInterpretationException( "Cannot dereference an entity name" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<?> resolveIndexedAccess(
|
||||
SqmExpression<?> selector,
|
||||
boolean isTerminal,
|
||||
SqmCreationState creationState) {
|
||||
throw new HqlInterpretationException( "Cannot dereference an entity name" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( getEntityValue().getName() );
|
||||
}
|
||||
}
|
|
@ -6,9 +6,12 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.any.annotations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.LazyInitializationException;
|
||||
import org.hibernate.query.spi.QueryImplementor;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
|
@ -16,6 +19,7 @@ import org.junit.jupiter.api.AfterEach;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
@ -31,6 +35,7 @@ import static org.junit.Assert.fail;
|
|||
LazyPropertySet.class,
|
||||
PropertyMap.class,
|
||||
PropertyList.class,
|
||||
PropertyHolder.class,
|
||||
CharProperty.class
|
||||
}
|
||||
)
|
||||
|
@ -41,48 +46,68 @@ public class AnyTest {
|
|||
scope.inTransaction(
|
||||
session -> {
|
||||
{
|
||||
final PropertySet set1 = new PropertySet("string");
|
||||
final Property property = new StringProperty("name", "Alex");
|
||||
set1.setSomeProperty(property);
|
||||
set1.addGeneralProperty(property);
|
||||
session.save(set1);
|
||||
final PropertySet set1 = new PropertySet( "string" );
|
||||
final Property property = new StringProperty( "name", "Alex" );
|
||||
set1.setSomeProperty( property );
|
||||
set1.addGeneralProperty( property );
|
||||
session.persist( set1 );
|
||||
|
||||
final PropertySet set2 = new PropertySet("integer");
|
||||
final Property property2 = new IntegerProperty("age", 33);
|
||||
set2.setSomeProperty(property2);
|
||||
set2.addGeneralProperty(property2);
|
||||
session.save(set2);
|
||||
final PropertySet set2 = new PropertySet( "integer" );
|
||||
final Property property2 = new IntegerProperty( "age", 33 );
|
||||
set2.setSomeProperty( property2 );
|
||||
set2.addGeneralProperty( property2 );
|
||||
session.persist( set2 );
|
||||
}
|
||||
|
||||
{
|
||||
final PropertyMap map = new PropertyMap("sample");
|
||||
map.getProperties().put("name", new StringProperty("name", "Alex"));
|
||||
map.getProperties().put("age", new IntegerProperty("age", 33));
|
||||
session.save(map);
|
||||
final PropertyMap map = new PropertyMap( "sample" );
|
||||
map.getProperties().put( "name", new StringProperty( "name", "Alex" ) );
|
||||
map.getProperties().put( "age", new IntegerProperty( "age", 33 ) );
|
||||
session.persist( map );
|
||||
}
|
||||
|
||||
{
|
||||
final PropertyList list = new PropertyList("sample");
|
||||
final StringProperty stringProperty = new StringProperty("name", "Alex");
|
||||
final IntegerProperty integerProperty = new IntegerProperty("age", 33);
|
||||
final LongProperty longProperty = new LongProperty("distance", 121L);
|
||||
final CharProperty charProp = new CharProperty("Est", 'E');
|
||||
StringProperty nameProperty = new StringProperty( "name", "John Doe" );
|
||||
session.persist( nameProperty );
|
||||
|
||||
list.setSomeProperty(longProperty);
|
||||
PropertyHolder namePropertyHolder = new PropertyHolder();
|
||||
namePropertyHolder.setId( 1 );
|
||||
namePropertyHolder.setProperty( nameProperty );
|
||||
|
||||
list.addGeneralProperty(stringProperty);
|
||||
list.addGeneralProperty(integerProperty);
|
||||
list.addGeneralProperty(longProperty);
|
||||
list.addGeneralProperty(charProp);
|
||||
session.persist( namePropertyHolder );
|
||||
|
||||
session.save(list);
|
||||
final IntegerProperty ageProperty = new IntegerProperty( "age", 23 );
|
||||
session.persist( ageProperty );
|
||||
|
||||
PropertyHolder agePropertyHolder = new PropertyHolder();
|
||||
agePropertyHolder.setId( 2 );
|
||||
agePropertyHolder.setProperty( ageProperty );
|
||||
|
||||
session.persist( agePropertyHolder );
|
||||
}
|
||||
|
||||
{
|
||||
final PropertyList list = new PropertyList( "sample" );
|
||||
final StringProperty stringProperty = new StringProperty( "name", "Alex" );
|
||||
final IntegerProperty integerProperty = new IntegerProperty( "age", 33 );
|
||||
final LongProperty longProperty = new LongProperty( "distance", 121L );
|
||||
final CharProperty charProp = new CharProperty( "Est", 'E' );
|
||||
|
||||
list.setSomeProperty( longProperty );
|
||||
|
||||
list.addGeneralProperty( stringProperty );
|
||||
list.addGeneralProperty( integerProperty );
|
||||
list.addGeneralProperty( longProperty );
|
||||
list.addGeneralProperty( charProp );
|
||||
|
||||
session.persist( list );
|
||||
}
|
||||
|
||||
{
|
||||
final LazyPropertySet set = new LazyPropertySet( "string" );
|
||||
final Property property = new StringProperty( "name", "Alex" );
|
||||
set.setSomeProperty( property );
|
||||
session.save( set );
|
||||
session.persist( set );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -92,14 +117,66 @@ public class AnyTest {
|
|||
public void dropTestData(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery( "delete StringProperty" ).executeUpdate();
|
||||
session.createQuery( "delete IntegerProperty" ).executeUpdate();
|
||||
session.createQuery( "delete LongProperty" ).executeUpdate();
|
||||
session.createQuery( "delete CharProperty" ).executeUpdate();
|
||||
session.createMutationQuery( "delete StringProperty" ).executeUpdate();
|
||||
session.createMutationQuery( "delete IntegerProperty" ).executeUpdate();
|
||||
session.createMutationQuery( "delete LongProperty" ).executeUpdate();
|
||||
session.createMutationQuery( "delete CharProperty" ).executeUpdate();
|
||||
|
||||
session.createQuery( "delete PropertyList" ).executeUpdate();
|
||||
session.createQuery( "delete PropertyMap" ).executeUpdate();
|
||||
session.createQuery( "delete PropertySet" ).executeUpdate();
|
||||
session.createMutationQuery( "delete PropertyHolder" ).executeUpdate();
|
||||
session.createMutationQuery( "delete PropertyList" ).executeUpdate();
|
||||
session.createMutationQuery( "delete PropertyMap" ).executeUpdate();
|
||||
session.createMutationQuery( "delete PropertySet" ).executeUpdate();
|
||||
session.createMutationQuery( "delete LazyPropertySet" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-15323")
|
||||
public void testHqlCollectionTypeQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
List<PropertySet> propertySets = session.createQuery(
|
||||
"select p from PropertySet p where type(p.generalProperties) = IntegerProperty ",
|
||||
PropertySet.class ).list();
|
||||
assertEquals( 1, propertySets.size() );
|
||||
|
||||
PropertySet propertySet = propertySets.get( 0 );
|
||||
assertEquals( 1, propertySet.getGeneralProperties().size() );
|
||||
|
||||
assertEquals( "age", propertySet.getGeneralProperties().get( 0 ).getName() );
|
||||
|
||||
propertySets = session.createQuery(
|
||||
"select p from PropertySet p where type(p.generalProperties) = StringProperty ",
|
||||
PropertySet.class ).list();
|
||||
assertEquals( 1, propertySets.size() );
|
||||
|
||||
propertySet = propertySets.get( 0 );
|
||||
assertEquals( 1, propertySet.getGeneralProperties().size() );
|
||||
|
||||
assertEquals( "name", propertySet.getGeneralProperties().get( 0 ).getName() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-15323")
|
||||
public void testHqlTypeQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
List<PropertyHolder> propertyHolders = session.createQuery(
|
||||
"select p from PropertyHolder p where type(p.property) = IntegerProperty ",
|
||||
PropertyHolder.class ).list();
|
||||
assertEquals( 1, propertyHolders.size() );
|
||||
|
||||
assertEquals( "age", propertyHolders.get( 0 ).getProperty().getName() );
|
||||
|
||||
propertyHolders = session.createQuery(
|
||||
"select p from PropertyHolder p where type(p.property) = StringProperty ",
|
||||
PropertyHolder.class ).list();
|
||||
assertEquals( 1, propertyHolders.size() );
|
||||
|
||||
assertEquals( "name", propertyHolders.get( 0 ).getProperty().getName() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -108,7 +185,10 @@ public class AnyTest {
|
|||
public void testDefaultAnyAssociation(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final QueryImplementor<PropertySet> query = session.createQuery("select s from PropertySet s where name = :name", PropertySet.class);
|
||||
final QueryImplementor<PropertySet> query = session.createQuery(
|
||||
"select s from PropertySet s where name = :name",
|
||||
PropertySet.class
|
||||
);
|
||||
|
||||
{
|
||||
final PropertySet result = query.setParameter( "name", "string" ).uniqueResult();
|
||||
|
@ -192,8 +272,11 @@ public class AnyTest {
|
|||
public void testFetchEager(SessionFactoryScope scope) {
|
||||
final PropertySet result = scope.fromTransaction(
|
||||
session -> {
|
||||
final PropertySet localResult = session.createQuery("select s from PropertySet s where name = :name", PropertySet.class)
|
||||
.setParameter("name", "string")
|
||||
final PropertySet localResult = session.createQuery(
|
||||
"select s from PropertySet s where name = :name",
|
||||
PropertySet.class
|
||||
)
|
||||
.setParameter( "name", "string" )
|
||||
.getSingleResult();
|
||||
assertNotNull( localResult );
|
||||
assertNotNull( localResult.getSomeProperty() );
|
||||
|
@ -210,8 +293,11 @@ public class AnyTest {
|
|||
public void testFetchLazy(SessionFactoryScope scope) {
|
||||
final LazyPropertySet result = scope.fromTransaction(
|
||||
session -> {
|
||||
final LazyPropertySet localResult = session.createQuery("select s from LazyPropertySet s where name = :name", LazyPropertySet.class)
|
||||
.setParameter("name", "string")
|
||||
final LazyPropertySet localResult = session.createQuery(
|
||||
"select s from LazyPropertySet s where name = :name",
|
||||
LazyPropertySet.class
|
||||
)
|
||||
.setParameter( "name", "string" )
|
||||
.getSingleResult();
|
||||
assertNotNull( localResult );
|
||||
assertNotNull( localResult.getSomeProperty() );
|
||||
|
|
|
@ -6,11 +6,14 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.any.annotations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.Any;
|
||||
import org.hibernate.annotations.AnyDiscriminator;
|
||||
import org.hibernate.annotations.AnyDiscriminatorValue;
|
||||
import org.hibernate.annotations.AnyKeyJavaClass;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
|
@ -33,6 +36,7 @@ import static org.junit.Assert.assertTrue;
|
|||
@DomainModel( annotatedClasses = { EmbeddedAnyTest.Foo.class, EmbeddedAnyTest.Bar1.class, EmbeddedAnyTest.Bar2.class } )
|
||||
@SessionFactory
|
||||
public class EmbeddedAnyTest {
|
||||
|
||||
@BeforeEach
|
||||
public void createTestData(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
|
@ -78,6 +82,28 @@ public class EmbeddedAnyTest {
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-15323")
|
||||
public void testEmbeddedTypeHql(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final List<Foo> foos = session.createQuery( "from Foo f where type(f.fooEmbedded.bar) = Bar1", Foo.class )
|
||||
.list();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-15323")
|
||||
public void testEmbeddedTypeHql2(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final List<Foo> foos = session.createQuery( "from Foo f where Bar1 = type(f.fooEmbedded.bar)", Foo.class )
|
||||
.list();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "Foo")
|
||||
public static class Foo {
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.any.annotations;
|
||||
|
||||
|
||||
public interface Property {
|
||||
|
||||
public String getName();
|
||||
public String asString();
|
||||
String getName();
|
||||
|
||||
String asString();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.orm.test.any.annotations;
|
||||
|
||||
import org.hibernate.annotations.Any;
|
||||
import org.hibernate.annotations.AnyDiscriminator;
|
||||
import org.hibernate.annotations.AnyDiscriminatorValue;
|
||||
import org.hibernate.annotations.AnyKeyJavaClass;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.DiscriminatorType;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "property_holder")
|
||||
public class PropertyHolder {
|
||||
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
@Any
|
||||
@AnyDiscriminator(DiscriminatorType.STRING)
|
||||
@AnyDiscriminatorValue(discriminator = "S", entity = StringProperty.class)
|
||||
@AnyDiscriminatorValue(discriminator = "I", entity = IntegerProperty.class)
|
||||
@AnyKeyJavaClass(Integer.class)
|
||||
@Column(name = "property_type")
|
||||
@JoinColumn(name = "property_id")
|
||||
private Property property;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Property getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
public void setProperty(Property property) {
|
||||
this.property = property;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue