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:
parent
340ba91e5c
commit
a4e4cb7260
|
@ -8,6 +8,7 @@ package org.hibernate.boot.model.convert.spi;
|
||||||
|
|
||||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||||
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access to information that implementors of
|
* Access to information that implementors of
|
||||||
|
@ -18,5 +19,9 @@ import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
||||||
*/
|
*/
|
||||||
public interface JpaAttributeConverterCreationContext {
|
public interface JpaAttributeConverterCreationContext {
|
||||||
ManagedBeanRegistry getManagedBeanRegistry();
|
ManagedBeanRegistry getManagedBeanRegistry();
|
||||||
JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry();
|
TypeConfiguration getTypeConfiguration();
|
||||||
|
|
||||||
|
default JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry() {
|
||||||
|
return getTypeConfiguration().getJavaTypeDescriptorRegistry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
|
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.RowVersionTypeDescriptor;
|
import org.hibernate.type.descriptor.java.RowVersionTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.TemporalJavaTypeDescriptor;
|
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.SqlTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
@ -239,8 +238,8 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry() {
|
public TypeConfiguration getTypeConfiguration() {
|
||||||
return typeConfiguration.getJavaTypeDescriptorRegistry();
|
return typeConfiguration;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -408,8 +407,8 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry() {
|
public TypeConfiguration getTypeConfiguration() {
|
||||||
return typeConfiguration.getJavaTypeDescriptorRegistry();
|
return typeConfiguration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -44,8 +44,6 @@ import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
|
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
|
||||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.BinaryType;
|
|
||||||
import org.hibernate.type.RowVersionType;
|
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
|
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
|
||||||
import org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter;
|
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.LobTypeMappings;
|
||||||
import org.hibernate.type.descriptor.sql.NationalizedTypeMappings;
|
import org.hibernate.type.descriptor.sql.NationalizedTypeMappings;
|
||||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
import org.hibernate.usertype.DynamicParameterizedType;
|
import org.hibernate.usertype.DynamicParameterizedType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -579,8 +578,8 @@ public abstract class SimpleValue implements KeyValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry() {
|
public TypeConfiguration getTypeConfiguration() {
|
||||||
return metadata.getTypeConfiguration().getJavaTypeDescriptorRegistry();
|
return getMetadata().getTypeConfiguration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -29,6 +29,7 @@ public interface JdbcMapping {
|
||||||
*/
|
*/
|
||||||
SqlTypeDescriptor getSqlTypeDescriptor();
|
SqlTypeDescriptor getSqlTypeDescriptor();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The strategy for extracting values of this expressable
|
* The strategy for extracting values of this expressable
|
||||||
* type from JDBC ResultSets, CallableStatements, etc
|
* type from JDBC ResultSets, CallableStatements, etc
|
||||||
|
|
|
@ -11,6 +11,8 @@ import java.sql.SQLException;
|
||||||
|
|
||||||
import org.hibernate.annotations.Remove;
|
import org.hibernate.annotations.Remove;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
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;
|
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +28,14 @@ public interface EnumValueConverter<O extends Enum, R> extends BasicValueConvert
|
||||||
|
|
||||||
String toSqlLiteral(Object value);
|
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
|
@Remove
|
||||||
|
@Deprecated
|
||||||
void writeValue(
|
void writeValue(
|
||||||
PreparedStatement statement,
|
PreparedStatement statement,
|
||||||
Enum value,
|
Enum value,
|
||||||
|
|
|
@ -137,6 +137,7 @@ import org.hibernate.metamodel.mapping.internal.BasicValuedSingularAttributeMapp
|
||||||
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
|
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
|
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
|
||||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
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.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||||
|
@ -6056,14 +6057,38 @@ public abstract class AbstractEntityPersister
|
||||||
final String[] attrColumnNames = getPropertyColumnNames( propertyIndex );
|
final String[] attrColumnNames = getPropertyColumnNames( propertyIndex );
|
||||||
|
|
||||||
if ( attrType instanceof BasicType ) {
|
if ( attrType instanceof BasicType ) {
|
||||||
return new BasicValuedSingularAttributeMapping(
|
final BasicValue.Resolution<?> resolution = ( (BasicValue) bootProperty.getValue() ).resolve();
|
||||||
attrName,
|
final BasicValueConverter valueConverter = resolution.getValueConverter();
|
||||||
tableExpression,
|
|
||||||
attrColumnNames[0],
|
if ( valueConverter != null ) {
|
||||||
( (BasicValue) bootProperty.getValue() ).resolve().getValueConverter(),
|
// we want to "decompose" the "type" into its various pieces as expected by the mapping
|
||||||
(BasicType) attrType,
|
assert valueConverter.getRelationalJavaDescriptor() == resolution.getRelationalJavaDescriptor();
|
||||||
(BasicType) attrType
|
|
||||||
);
|
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
|
// todo (6.0) : for now ignore any non basic-typed attributes
|
||||||
|
|
|
@ -68,9 +68,7 @@ public class ColumnReference implements Expression {
|
||||||
// todo (6.0) : potential use for runtime database model - interpretation of table and column references
|
// 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
|
// into metadata info such as java/sql type, binder, extractor
|
||||||
|
|
||||||
final ValueExtractor jdbcValueExtractor = jdbcMapping.getJdbcValueExtractor();
|
return new SqlSelectionImpl( jdbcPosition, valuesArrayPosition, this, jdbcMapping );
|
||||||
|
|
||||||
return new SqlSelectionImpl( jdbcPosition, valuesArrayPosition, this, jdbcValueExtractor );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,29 +9,42 @@ package org.hibernate.sql.results.internal;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
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.SqlAstWalker;
|
||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.type.descriptor.ValueExtractor;
|
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
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class SqlSelectionImpl implements SqlSelection {
|
public class SqlSelectionImpl implements SqlSelection {
|
||||||
private final int jdbcPosition;
|
private final int jdbcPosition;
|
||||||
private final int valuesArrayPosition;
|
private final int valuesArrayPosition;
|
||||||
private final Expression sqlExpression;
|
private final Expression sqlExpression;
|
||||||
private final ValueExtractor jdbcValueExtractor;
|
private final JdbcMapping jdbcMapping;
|
||||||
|
|
||||||
public SqlSelectionImpl(int jdbcPosition, int valuesArrayPosition, Expression sqlExpression, 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.jdbcPosition = jdbcPosition;
|
||||||
this.valuesArrayPosition = valuesArrayPosition;
|
this.valuesArrayPosition = valuesArrayPosition;
|
||||||
this.sqlExpression = sqlExpression;
|
this.sqlExpression = sqlExpression;
|
||||||
this.jdbcValueExtractor = jdbcValueExtractor;
|
this.jdbcMapping = jdbcMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression getWrappedSqlExpression() {
|
public Expression getWrappedSqlExpression() {
|
||||||
|
@ -40,7 +53,9 @@ public class SqlSelectionImpl implements SqlSelection {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValueExtractor getJdbcValueExtractor() {
|
public ValueExtractor getJdbcValueExtractor() {
|
||||||
return jdbcValueExtractor;
|
return ( (SqlExpressable) sqlExpression.getExpressionType() ).getJdbcMapping().getJdbcValueExtractor();
|
||||||
|
// return jdbcValueExtractor;
|
||||||
|
// return jdbcMapping.getJdbcValueExtractor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.SimpleEntity;
|
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.query.spi.QueryImplementor;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
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
|
@Test
|
||||||
@FailureExpected( reason = "Support for entity-values DomainResults not yet implemented")
|
@FailureExpected( reason = "Support for entity-values DomainResults not yet implemented")
|
||||||
public void testSelectEntityHqlExecution(SessionFactoryScope scope) {
|
public void testSelectEntityHqlExecution(SessionFactoryScope scope) {
|
||||||
|
|
Loading…
Reference in New Issue