Initial working support for building and executing JdbcSelect operation from simple HQL for a converted (enum) value - actually reading;

fixed (temporary) support for writing enumerated values
This commit is contained in:
Steve Ebersole 2019-09-05 09:40:47 -05:00 committed by Andrea Boriero
parent 340ba91e5c
commit a4e4cb7260
9 changed files with 95 additions and 28 deletions

View File

@ -8,6 +8,7 @@ package org.hibernate.boot.model.convert.spi;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Access to information that implementors of
@ -18,5 +19,9 @@ import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
*/
public interface JpaAttributeConverterCreationContext {
ManagedBeanRegistry getManagedBeanRegistry();
JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry();
TypeConfiguration getTypeConfiguration();
default JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry() {
return getTypeConfiguration().getJavaTypeDescriptorRegistry();
}
}

View File

@ -42,7 +42,6 @@ import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
import org.hibernate.type.descriptor.java.RowVersionTypeDescriptor;
import org.hibernate.type.descriptor.java.TemporalJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
import org.hibernate.type.spi.TypeConfiguration;
@ -239,8 +238,8 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
}
@Override
public JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry() {
return typeConfiguration.getJavaTypeDescriptorRegistry();
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
};
@ -408,8 +407,8 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
}
@Override
public JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry() {
return typeConfiguration.getJavaTypeDescriptorRegistry();
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
}
)

View File

@ -44,8 +44,6 @@ import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.BinaryType;
import org.hibernate.type.RowVersionType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter;
@ -54,6 +52,7 @@ import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
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;
/**
@ -579,8 +578,8 @@ public abstract class SimpleValue implements KeyValue {
}
@Override
public org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry() {
return metadata.getTypeConfiguration().getJavaTypeDescriptorRegistry();
public TypeConfiguration getTypeConfiguration() {
return getMetadata().getTypeConfiguration();
}
}
);

View File

@ -29,6 +29,7 @@ public interface JdbcMapping {
*/
SqlTypeDescriptor getSqlTypeDescriptor();
/**
* The strategy for extracting values of this expressable
* type from JDBC ResultSets, CallableStatements, etc

View File

@ -11,6 +11,8 @@ import java.sql.SQLException;
import org.hibernate.annotations.Remove;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
/**
@ -26,7 +28,14 @@ public interface EnumValueConverter<O extends Enum, R> extends BasicValueConvert
String toSqlLiteral(Object value);
/**
* @since 6.0
*
* @deprecated Added temporarily in support of dual SQL execution until fully migrated
* to {@link SelectStatement} and {@link JdbcOperation}
*/
@Remove
@Deprecated
void writeValue(
PreparedStatement statement,
Enum value,

View File

@ -137,6 +137,7 @@ import org.hibernate.metamodel.mapping.internal.BasicValuedSingularAttributeMapp
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.spi.PersisterCreationContext;
@ -6056,14 +6057,38 @@ public abstract class AbstractEntityPersister
final String[] attrColumnNames = getPropertyColumnNames( propertyIndex );
if ( attrType instanceof BasicType ) {
return new BasicValuedSingularAttributeMapping(
attrName,
tableExpression,
attrColumnNames[0],
( (BasicValue) bootProperty.getValue() ).resolve().getValueConverter(),
(BasicType) attrType,
(BasicType) attrType
);
final BasicValue.Resolution<?> resolution = ( (BasicValue) bootProperty.getValue() ).resolve();
final BasicValueConverter valueConverter = resolution.getValueConverter();
if ( valueConverter != null ) {
// we want to "decompose" the "type" into its various pieces as expected by the mapping
assert valueConverter.getRelationalJavaDescriptor() == resolution.getRelationalJavaDescriptor();
final BasicType<?> mappingBasicType = creationProcess.getCreationContext()
.getDomainModel()
.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( valueConverter.getRelationalJavaDescriptor(), resolution.getRelationalSqlTypeDescriptor() );
return new BasicValuedSingularAttributeMapping(
attrName,
tableExpression,
attrColumnNames[0],
valueConverter,
mappingBasicType,
mappingBasicType.getJdbcMapping()
);
}
else {
return new BasicValuedSingularAttributeMapping(
attrName,
tableExpression,
attrColumnNames[0],
null,
(BasicType) attrType,
(BasicType) attrType
);
}
}
// todo (6.0) : for now ignore any non basic-typed attributes

View File

@ -68,9 +68,7 @@ public class ColumnReference implements Expression {
// todo (6.0) : potential use for runtime database model - interpretation of table and column references
// into metadata info such as java/sql type, binder, extractor
final ValueExtractor jdbcValueExtractor = jdbcMapping.getJdbcValueExtractor();
return new SqlSelectionImpl( jdbcPosition, valuesArrayPosition, this, jdbcValueExtractor );
return new SqlSelectionImpl( jdbcPosition, valuesArrayPosition, this, jdbcMapping );
}
@Override

View File

@ -9,29 +9,42 @@ package org.hibernate.sql.results.internal;
import java.util.Objects;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.SqlExpressable;
import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.type.descriptor.ValueExtractor;
/**
* @asciidoc
*
* ````
* @Entity
* class MyEntity {
* ...
* @Column( name = "the_column", ... )
* public String getTheColumn() { ... }
*
* @Convert( ... )
* @Column( name = "the_column", ... )
* ConvertedType getTheConvertedColumn() { ... }
*
* }
* ````
*
* @author Steve Ebersole
*/
public class SqlSelectionImpl implements SqlSelection {
private final int jdbcPosition;
private final int valuesArrayPosition;
private final Expression sqlExpression;
private final ValueExtractor jdbcValueExtractor;
private final JdbcMapping jdbcMapping;
public SqlSelectionImpl(int jdbcPosition, int valuesArrayPosition, Expression sqlExpression, JdbcMapping jdbcMapping) {
this( jdbcPosition, valuesArrayPosition, sqlExpression, jdbcMapping.getJdbcValueExtractor() );
}
public SqlSelectionImpl(int jdbcPosition, int valuesArrayPosition, Expression sqlExpression, ValueExtractor jdbcValueExtractor) {
this.jdbcPosition = jdbcPosition;
this.valuesArrayPosition = valuesArrayPosition;
this.sqlExpression = sqlExpression;
this.jdbcValueExtractor = jdbcValueExtractor;
this.jdbcMapping = jdbcMapping;
}
public Expression getWrappedSqlExpression() {
@ -40,7 +53,9 @@ public class SqlSelectionImpl implements SqlSelection {
@Override
public ValueExtractor getJdbcValueExtractor() {
return jdbcValueExtractor;
return ( (SqlExpressable) sqlExpression.getExpressionType() ).getJdbcMapping().getJdbcValueExtractor();
// return jdbcValueExtractor;
// return jdbcMapping.getJdbcValueExtractor();
}
@Override

View File

@ -11,6 +11,7 @@ import java.util.List;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.SimpleEntity;
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.testing.orm.junit.DomainModel;
@ -86,6 +87,21 @@ public class SmokeTests {
);
}
@Test
public void testSelectGenderHql(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
final QueryImplementor<Gender> query = session.createQuery(
"select e.gender from SimpleEntity e",
Gender.class
);
List<Gender> simpleEntities = query.list();
assertThat( simpleEntities.size(), is( 1 ) );
assertThat( simpleEntities.get( 0 ), is( FEMALE ) );
}
);
}
@Test
@FailureExpected( reason = "Support for entity-values DomainResults not yet implemented")
public void testSelectEntityHqlExecution(SessionFactoryScope scope) {