HHH-15442 Use ConvertedBasicTypeImpl and AnyDiscriminatorConverter

This commit is contained in:
Andrea Boriero 2022-08-10 11:19:01 +02:00 committed by Andrea Boriero
parent 863f045bf8
commit 47c3a41308
10 changed files with 115 additions and 134 deletions

View File

@ -51,6 +51,7 @@ import org.hibernate.property.access.internal.PropertyAccessMapImpl;
import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Getter;
import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.type.AnyType; import org.hibernate.type.AnyType;
import org.hibernate.type.BasicType;
import org.hibernate.type.EmbeddedComponentType; import org.hibernate.type.EmbeddedComponentType;
import org.hibernate.type.EntityType; import org.hibernate.type.EntityType;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
@ -242,7 +243,7 @@ public class AttributeFactory {
final JavaType<Y> baseJtd = context.getTypeConfiguration() final JavaType<Y> baseJtd = context.getTypeConfiguration()
.getJavaTypeRegistry() .getJavaTypeRegistry()
.resolveDescriptor( anyType.getReturnedClass() ); .resolveDescriptor( anyType.getReturnedClass() );
return new AnyMappingDomainTypeImpl<>( anyType, baseJtd ); return (DomainType<Y>) new AnyMappingDomainTypeImpl( anyType, (JavaType<Class>) baseJtd, context.getTypeConfiguration() );
} }
case EMBEDDABLE: { case EMBEDDABLE: {
final Component component = (Component) typeContext.getHibernateValue(); final Component component = (Component) typeContext.getHibernateValue();

View File

@ -0,0 +1,69 @@
/*
* 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.RepresentationMode;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.BasicType;
import org.hibernate.type.MetaType;
import org.hibernate.type.descriptor.java.ClassJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.spi.TypeConfiguration;
public class AnyDiscriminatorConverter implements BasicValueConverter<Class, Object> {
private final MetaType modelPart;
private BasicType discriminatorBasicType;
private TypeConfiguration typeConfiguration;
public AnyDiscriminatorConverter(
MetaType modelPart, BasicType discriminatorBasicType,
TypeConfiguration typeConfiguration) {
this.modelPart = modelPart;
this.discriminatorBasicType = discriminatorBasicType;
this.typeConfiguration = typeConfiguration;
}
@Override
public Class toDomainValue(Object discriminatorValue) {
if ( discriminatorValue == null ) {
return null;
}
final String entityName = modelPart.getDiscriminatorValuesToEntityNameMap().get( discriminatorValue );
final EntityPersister entityDescriptor = typeConfiguration.getSessionFactory()
.getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( entityName );
assert entityDescriptor.getRepresentationStrategy().getMode() == RepresentationMode.POJO;
return entityDescriptor.getJavaType().getJavaTypeClass();
}
@Override
public Object toRelationalValue(Class domainForm) {
if ( domainForm == null ) {
return null;
}
return modelPart.getEntityNameToDiscriminatorValueMap().get( ( domainForm ).getName() );
}
@Override
public JavaType<Class> getDomainJavaType() {
return getExpressibleJavaType();
}
@Override
public JavaType<Object> getRelationalJavaType() {
return discriminatorBasicType.getJavaTypeDescriptor();
}
public JavaType<Class> getExpressibleJavaType() {
return ClassJavaType.INSTANCE;
}
}

View File

@ -1,102 +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 org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.sql.ast.Clause;
import org.hibernate.type.BasicType;
import org.hibernate.type.MetaType;
import org.hibernate.type.descriptor.java.ClassJavaType;
import org.hibernate.type.descriptor.java.JavaType;
public class AnyDiscriminatorDomainTypeImpl<T>
implements SimpleDomainType<T>, MappingModelExpressible<T>, BasicValueConverter<T, Object> {
private final BasicType underlyingType;
private final MetaType modelPart;
public AnyDiscriminatorDomainTypeImpl(BasicType<?> underlyingType, MetaType modelPart) {
this.underlyingType = underlyingType;
this.modelPart = modelPart;
}
@Override
public T toDomainValue(Object discriminatorValue) {
if ( discriminatorValue == null ) {
return null;
}
return (T) modelPart.getDiscriminatorValuesToEntityNameMap().get( discriminatorValue );
}
@Override
public Object toRelationalValue(T domainForm) {
if ( domainForm == null ) {
return null;
}
if ( domainForm instanceof Class ) {
return modelPart.getEntityNameToDiscriminatorValueMap().get( ( (Class) domainForm ).getName() );
}
else {
return modelPart.getEntityNameToDiscriminatorValueMap().get( (String) domainForm );
}
}
@Override
public JavaType<T> getDomainJavaType() {
return getExpressibleJavaType();
}
@Override
public JavaType<Object> getRelationalJavaType() {
return underlyingType.getExpressibleJavaType();
}
@Override
public PersistenceType getPersistenceType() {
return PersistenceType.BASIC;
}
@Override
public Class getJavaType() {
return Class.class;
}
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
return toRelationalValue( (T) value );
}
@Override
public int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
valuesConsumer.consume( offset, value, underlyingType );
return 1;
}
public JavaType<T> getExpressibleJavaType() {
return (JavaType<T>) ClassJavaType.INSTANCE;
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( 0, underlyingType );
return 1;
}
public BasicType getBasicType() {
return underlyingType;
}
}

View File

@ -7,10 +7,12 @@
package org.hibernate.metamodel.model.domain.internal; package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.mapping.CollectionPart; import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.query.ReturnableType; import org.hibernate.query.ReturnableType;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.spi.NavigablePath; import org.hibernate.spi.NavigablePath;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
/** /**
@ -22,7 +24,7 @@ public class AnyDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
public AnyDiscriminatorSqmPathSource( public AnyDiscriminatorSqmPathSource(
String localPathName, String localPathName,
AnyDiscriminatorDomainTypeImpl domainType, SimpleDomainType<D> domainType,
BindableType jpaBindableType) { BindableType jpaBindableType) {
super( localPathName, domainType, jpaBindableType ); super( localPathName, domainType, jpaBindableType );
} }
@ -55,8 +57,8 @@ public class AnyDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
} }
@Override @Override
public AnyDiscriminatorDomainTypeImpl<D> getSqmPathType() { public BasicType<D> getSqmPathType() {
return (AnyDiscriminatorDomainTypeImpl<D>) super.getSqmPathType(); return (BasicType<D>) super.getSqmPathType();
} }
@Override @Override

View File

@ -10,24 +10,31 @@ import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.metamodel.model.domain.SimpleDomainType; import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.type.AnyType; import org.hibernate.type.AnyType;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.ConvertedBasicType;
import org.hibernate.type.MetaType; import org.hibernate.type.MetaType;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class AnyMappingDomainTypeImpl<T> implements AnyMappingDomainType<T> { public class AnyMappingDomainTypeImpl implements AnyMappingDomainType<Class> {
private final AnyType anyType; private final AnyType anyType;
private final JavaType<T> baseJtd; private final JavaType<Class> baseJtd;
private final AnyDiscriminatorDomainTypeImpl<?> anyDiscriminatorType; private final BasicType<Class> anyDiscriminatorType;
public AnyMappingDomainTypeImpl(AnyType anyType, JavaType<T> baseJtd) { public AnyMappingDomainTypeImpl(AnyType anyType, JavaType<Class> baseJtd, TypeConfiguration typeConfiguration) {
this.anyType = anyType; this.anyType = anyType;
this.baseJtd = baseJtd; this.baseJtd = baseJtd;
final MetaType discriminatorType = (MetaType) anyType.getDiscriminatorType(); final MetaType discriminatorType = (MetaType) anyType.getDiscriminatorType();
anyDiscriminatorType = new AnyDiscriminatorDomainTypeImpl<>( final BasicType discriminatorBasicType = (BasicType) discriminatorType.getBaseType();
(BasicType<?>) discriminatorType.getBaseType(), anyDiscriminatorType =
discriminatorType); new ConvertedBasicTypeImpl<>(
null, // no name
discriminatorBasicType.getJdbcType(),
new AnyDiscriminatorConverter( discriminatorType, discriminatorBasicType, typeConfiguration )
);
} }
@Override @Override
@ -35,23 +42,25 @@ public class AnyMappingDomainTypeImpl<T> implements AnyMappingDomainType<T> {
return PersistenceType.ENTITY; return PersistenceType.ENTITY;
} }
@Override @SuppressWarnings("unchecked") @Override
public Class<T> getJavaType() { @SuppressWarnings("unchecked")
return (Class<T>) anyType.getReturnedClass(); public Class<Class> getJavaType() {
return (Class<Class>) anyType.getReturnedClass();
} }
@Override @Override
public JavaType<T> getExpressibleJavaType() { public JavaType<Class> getExpressibleJavaType() {
return baseJtd; return baseJtd;
} }
@Override @Override
public AnyDiscriminatorDomainTypeImpl<?> getDiscriminatorType() { public BasicType<Class> getDiscriminatorType() {
return anyDiscriminatorType; return anyDiscriminatorType;
} }
@Override @Override
public SimpleDomainType<?> getKeyType() { public SimpleDomainType getKeyType() {
return (BasicType<?>) anyType.getIdentifierType(); return (BasicType<?>) anyType.getIdentifierType();
} }
} }

View File

@ -13,6 +13,8 @@ import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.type.BasicType;
import org.hibernate.type.ConvertedBasicType;
import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRIBUTE; import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRIBUTE;
@ -31,7 +33,8 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
keyPathSource = new BasicSqmPathSource<>( "id", (BasicDomainType<?>) domainType.getKeyType(), SINGULAR_ATTRIBUTE ); keyPathSource = new BasicSqmPathSource<>( "id", (BasicDomainType<?>) domainType.getKeyType(), SINGULAR_ATTRIBUTE );
discriminatorPathSource = new AnyDiscriminatorSqmPathSource<>( discriminatorPathSource = new AnyDiscriminatorSqmPathSource<>(
localPathName, localPathName,
(AnyDiscriminatorDomainTypeImpl) domainType.getDiscriminatorType(), jpaBindableType domainType.getDiscriminatorType(),
jpaBindableType
); );
} }

View File

@ -55,6 +55,7 @@ import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType; import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute; import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute; 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.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath; import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.EntitySqmPathSource; import org.hibernate.metamodel.model.domain.internal.EntitySqmPathSource;
@ -2156,8 +2157,6 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
AnyDiscriminatorSqmPath anyDiscriminatorTypeSqmPath, AnyDiscriminatorSqmPath anyDiscriminatorTypeSqmPath,
HqlParser.ExpressionContext valueExpressionContext) { HqlParser.ExpressionContext valueExpressionContext) {
return new SqmAnyDiscriminatorValue<>( return new SqmAnyDiscriminatorValue<>(
creationContext.getJpaMetamodel()
.entity( anyDiscriminatorTypeSqmPath.findRoot().getNavigablePath().getLocalName() ),
anyDiscriminatorTypeSqmPath.getNodeType().getPathName(), anyDiscriminatorTypeSqmPath.getNodeType().getPathName(),
creationContext.getJpaMetamodel().resolveHqlEntityReference( valueExpressionContext.getText() ), creationContext.getJpaMetamodel().resolveHqlEntityReference( valueExpressionContext.getText() ),
anyDiscriminatorTypeSqmPath.getExpressible().getSqmPathType(), anyDiscriminatorTypeSqmPath.getExpressible().getSqmPathType(),

View File

@ -98,7 +98,7 @@ import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath; import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPath;
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPathSource; import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPathSource;
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorDomainTypeImpl; import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorConverter;
import org.hibernate.query.derived.AnonymousTupleTableGroupProducer; import org.hibernate.query.derived.AnonymousTupleTableGroupProducer;
import org.hibernate.query.derived.AnonymousTupleType; import org.hibernate.query.derived.AnonymousTupleType;
import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource; import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource;
@ -378,6 +378,7 @@ import org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiati
import org.hibernate.sql.results.internal.SqlSelectionImpl; import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl; import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.ConvertedBasicType;
import org.hibernate.type.CustomType; import org.hibernate.type.CustomType;
import org.hibernate.type.EnumType; import org.hibernate.type.EnumType;
import org.hibernate.type.JavaObjectType; import org.hibernate.type.JavaObjectType;
@ -6237,10 +6238,10 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override @Override
public Expression visitAnyDiscriminatorTypeValueExpression(SqmAnyDiscriminatorValue expression) { public Expression visitAnyDiscriminatorTypeValueExpression(SqmAnyDiscriminatorValue expression) {
final AnyDiscriminatorDomainTypeImpl domainType = expression.getDomainType(); final BasicType domainType = expression.getDomainType();
return new QueryLiteral<>( return new QueryLiteral<>(
domainType.toRelationalValue( expression.getEntityValue().getHibernateEntityName() ), domainType.getValueConverter().toRelationalValue( expression.getEntityValue().getJavaType() ),
domainType.getBasicType() domainType
); );
} }

View File

@ -7,7 +7,6 @@
package org.hibernate.query.sqm.tree.expression; package org.hibernate.query.sqm.tree.expression;
import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorDomainTypeImpl;
import org.hibernate.query.hql.HqlInterpretationException; import org.hibernate.query.hql.HqlInterpretationException;
import org.hibernate.query.hql.spi.SemanticPathPart; import org.hibernate.query.hql.spi.SemanticPathPart;
import org.hibernate.query.hql.spi.SqmCreationState; import org.hibernate.query.hql.spi.SqmCreationState;
@ -16,27 +15,27 @@ import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.select.SqmSelectableNode; import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
import org.hibernate.type.BasicType;
public class SqmAnyDiscriminatorValue<T> extends AbstractSqmExpression<T> public class SqmAnyDiscriminatorValue<T> extends AbstractSqmExpression<T>
implements SqmSelectableNode<T>, SemanticPathPart { implements SqmSelectableNode<T>, SemanticPathPart {
private final EntityDomainType value; private final EntityDomainType value;
private final AnyDiscriminatorDomainTypeImpl domainType; private final BasicType domainType;
private final String pathName; private final String pathName;
public SqmAnyDiscriminatorValue( public SqmAnyDiscriminatorValue(
EntityDomainType<T> entityWithDiscriminator,
String pathName, String pathName,
EntityDomainType entityValue, EntityDomainType entityValue,
AnyDiscriminatorDomainTypeImpl domainType, BasicType<T> domainType,
NodeBuilder nodeBuilder) { NodeBuilder nodeBuilder) {
super( entityWithDiscriminator, nodeBuilder ); super( domainType, nodeBuilder );
this.value = entityValue; this.value = entityValue;
this.pathName = pathName; this.pathName = pathName;
this.domainType = domainType; this.domainType = domainType;
} }
public AnyDiscriminatorDomainTypeImpl getDomainType(){ public BasicType<T> getDomainType(){
return domainType; return domainType;
} }
@ -49,7 +48,6 @@ public class SqmAnyDiscriminatorValue<T> extends AbstractSqmExpression<T>
final SqmAnyDiscriminatorValue<T> expression = context.registerCopy( final SqmAnyDiscriminatorValue<T> expression = context.registerCopy(
this, this,
new SqmAnyDiscriminatorValue<>( new SqmAnyDiscriminatorValue<>(
(EntityDomainType) getNodeType(),
pathName, pathName,
value, value,
domainType, domainType,

View File

@ -300,7 +300,8 @@ public class AnyTest {
} }
@Test @Test
public void testMetaDataUseWithManyToAny(SessionFactoryScope scope) { public void
testMetaDataUseWithManyToAny(SessionFactoryScope scope) {
scope.inTransaction( scope.inTransaction(
session -> { session -> {
//noinspection unchecked //noinspection unchecked