HHH-17859, HHH-17858 function() and column() functions
This commit is contained in:
parent
1ba67c2de9
commit
6441c60255
|
@ -11,7 +11,6 @@ import org.hibernate.query.sqm.ComparisonOperator;
|
|||
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||
import org.hibernate.sql.ast.tree.Statement;
|
||||
import org.hibernate.sql.ast.tree.cte.CteMaterialization;
|
||||
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||
import org.hibernate.sql.ast.tree.expression.Any;
|
||||
import org.hibernate.sql.ast.tree.expression.Every;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
|
|
|
@ -158,6 +158,7 @@ BY : [bB] [yY];
|
|||
CASE : [cC] [aA] [sS] [eE];
|
||||
CAST : [cC] [aA] [sS] [tT];
|
||||
COLLATE : [cC] [oO] [lL] [lL] [aA] [tT] [eE];
|
||||
COLUMN : [cC] [oO] [lL] [uU] [mM] [nN];
|
||||
CONFLICT : [cC] [oO] [nN] [fF] [lL] [iI] [cC] [tT];
|
||||
CONSTRAINT : [cC] [oO] [nN] [sS] [tT] [rR] [aA] [iI] [nN] [tT];
|
||||
COUNT : [cC] [oO] [uU] [nN] [tT];
|
||||
|
|
|
@ -1083,6 +1083,7 @@ function
|
|||
| collectionAggregateFunction
|
||||
| collectionFunctionMisuse
|
||||
| jpaNonstandardFunction
|
||||
| columnFunction
|
||||
| genericFunction
|
||||
;
|
||||
|
||||
|
@ -1090,7 +1091,7 @@ function
|
|||
* A syntax for calling user-defined or native database functions, required by JPQL
|
||||
*/
|
||||
jpaNonstandardFunction
|
||||
: FUNCTION LEFT_PAREN jpaNonstandardFunctionName (COMMA genericFunctionArguments)? RIGHT_PAREN
|
||||
: FUNCTION LEFT_PAREN jpaNonstandardFunctionName (AS castTarget)? (COMMA genericFunctionArguments)? RIGHT_PAREN
|
||||
;
|
||||
|
||||
/**
|
||||
|
@ -1098,8 +1099,13 @@ jpaNonstandardFunction
|
|||
*/
|
||||
jpaNonstandardFunctionName
|
||||
: STRING_LITERAL
|
||||
| identifier
|
||||
;
|
||||
|
||||
columnFunction
|
||||
: COLUMN LEFT_PAREN path DOT jpaNonstandardFunctionName (AS castTarget)? RIGHT_PAREN
|
||||
;
|
||||
|
||||
/**
|
||||
* Any function invocation that follows the regular syntax
|
||||
*
|
||||
|
@ -1618,6 +1624,7 @@ rollup
|
|||
| CASE
|
||||
| CAST
|
||||
| COLLATE
|
||||
| COLUMN
|
||||
| CONFLICT
|
||||
| CONSTRAINT
|
||||
| COUNT
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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.dialect.function;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.hql.HqlInterpretationException;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.update.Assignable;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.JavaObjectType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class SqlColumn extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
private final String columnName;
|
||||
|
||||
public SqlColumn(String columnName, BasicType<?> type) {
|
||||
super(
|
||||
"column",
|
||||
StandardArgumentsValidators.min( 1 ),
|
||||
StandardFunctionReturnTypeResolvers.invariant( type == null ? JavaObjectType.INSTANCE : type ),
|
||||
null
|
||||
);
|
||||
this.columnName = columnName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final SqlAstNode sqlAstNode = arguments.get(0);
|
||||
final ColumnReference reference;
|
||||
if ( sqlAstNode instanceof Assignable ) {
|
||||
final Assignable assignable = (Assignable) sqlAstNode;
|
||||
reference = assignable.getColumnReferences().get(0);
|
||||
}
|
||||
else if ( sqlAstNode instanceof Expression ) {
|
||||
final Expression expression = (Expression) sqlAstNode;
|
||||
reference = expression.getColumnReference();
|
||||
}
|
||||
else {
|
||||
throw new HqlInterpretationException( "path did not map to a column" );
|
||||
}
|
||||
sqlAppender.appendSql( reference.getQualifier() );
|
||||
sqlAppender.appendSql( '.' );
|
||||
sqlAppender.appendSql( columnName );
|
||||
}
|
||||
|
||||
}
|
|
@ -62,7 +62,7 @@ public interface ConnectionProvider extends Service, Wrapped {
|
|||
* <p>
|
||||
* Typically, this is only true in managed environments where a container tracks connections
|
||||
* by transaction or thread.
|
||||
*
|
||||
* <p>
|
||||
* Note that JTA semantic depends on the fact that the underlying connection provider does
|
||||
* support aggressive release.
|
||||
*
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Set;
|
|||
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||
import org.hibernate.dialect.function.SqlColumn;
|
||||
import org.hibernate.grammars.hql.HqlLexer;
|
||||
import org.hibernate.grammars.hql.HqlParser;
|
||||
import org.hibernate.grammars.hql.HqlParserBaseVisitor;
|
||||
|
@ -58,7 +59,6 @@ import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
|
|||
import org.hibernate.query.NullPrecedence;
|
||||
import org.hibernate.query.ParameterLabelException;
|
||||
import org.hibernate.query.PathException;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.SortDirection;
|
||||
import org.hibernate.query.SyntaxException;
|
||||
|
@ -277,6 +277,9 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
private static final Logger log = Logger.getLogger( SemanticQueryBuilder.class );
|
||||
private static final Set<String> JPA_STANDARD_FUNCTIONS;
|
||||
|
||||
private static final BasicTypeImpl<Object> OBJECT_BASIC_TYPE =
|
||||
new BasicTypeImpl<>( new UnknownBasicJavaType<>(Object.class), ObjectJdbcType.INSTANCE );
|
||||
|
||||
static {
|
||||
final Set<String> jpaStandardFunctions = new HashSet<>();
|
||||
// Extracted from the BNF in JPA spec 4.14.
|
||||
|
@ -3910,43 +3913,64 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Functions
|
||||
|
||||
private String toName(HqlParser.JpaNonstandardFunctionNameContext ctx) {
|
||||
return ctx.STRING_LITERAL() == null
|
||||
? ctx.identifier().getText().toLowerCase()
|
||||
: unquoteStringLiteral( ctx.STRING_LITERAL().getText() ).toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmExpression<?> visitJpaNonstandardFunction(HqlParser.JpaNonstandardFunctionContext ctx) {
|
||||
final String functionName = unquoteStringLiteral( ctx.jpaNonstandardFunctionName().getText() ).toLowerCase();
|
||||
final List<SqmTypedNode<?>> functionArguments;
|
||||
if ( ctx.getChildCount() > 4 ) {
|
||||
//noinspection unchecked
|
||||
functionArguments = (List<SqmTypedNode<?>>) ctx.genericFunctionArguments().accept( this );
|
||||
}
|
||||
else {
|
||||
functionArguments = emptyList();
|
||||
}
|
||||
final String functionName = toName( ctx.jpaNonstandardFunctionName() );
|
||||
final HqlParser.GenericFunctionArgumentsContext argumentsContext = ctx.genericFunctionArguments();
|
||||
@SuppressWarnings("unchecked")
|
||||
final List<SqmTypedNode<?>> functionArguments =
|
||||
argumentsContext == null
|
||||
? emptyList()
|
||||
: (List<SqmTypedNode<?>>) argumentsContext.accept(this);
|
||||
|
||||
final BasicType<?> returnableType = returnType( ctx.castTarget() );
|
||||
SqmFunctionDescriptor functionTemplate = getFunctionDescriptor( functionName );
|
||||
if (functionTemplate == null) {
|
||||
if ( functionTemplate == null ) {
|
||||
functionTemplate = new NamedSqmFunctionDescriptor(
|
||||
functionName,
|
||||
true,
|
||||
null,
|
||||
StandardFunctionReturnTypeResolvers.invariant(
|
||||
new BasicTypeImpl<>(
|
||||
new UnknownBasicJavaType<>( Object.class ),
|
||||
ObjectJdbcType.INSTANCE
|
||||
)
|
||||
),
|
||||
StandardFunctionReturnTypeResolvers.invariant(returnableType),
|
||||
null
|
||||
);
|
||||
}
|
||||
return functionTemplate.generateSqmExpression(
|
||||
functionArguments,
|
||||
null,
|
||||
returnableType,
|
||||
creationContext.getQueryEngine()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmExpression<?> visitColumnFunction(HqlParser.ColumnFunctionContext ctx) {
|
||||
final String columnName = toName( ctx.jpaNonstandardFunctionName() );
|
||||
final SemanticPathPart semanticPathPart = visitPath( ctx.path() );
|
||||
final BasicType<?> resultType = returnType( ctx.castTarget() );
|
||||
return new SqlColumn( columnName, resultType ).generateSqmExpression(
|
||||
(SqmTypedNode<?>) semanticPathPart,
|
||||
resultType,
|
||||
creationContext.getQueryEngine()
|
||||
);
|
||||
}
|
||||
|
||||
private BasicType<?> returnType(HqlParser.CastTargetContext castTarget) {
|
||||
if ( castTarget == null ) {
|
||||
return OBJECT_BASIC_TYPE;
|
||||
}
|
||||
else {
|
||||
return (BasicType<?>) visitCastTarget( castTarget ).getType();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitGenericFunctionName(HqlParser.GenericFunctionNameContext ctx) {
|
||||
StringBuilder functionName = new StringBuilder( visitIdentifier( ctx.simplePath().identifier() ) );
|
||||
final StringBuilder functionName = new StringBuilder( visitIdentifier( ctx.simplePath().identifier() ) );
|
||||
for ( HqlParser.SimplePathElementContext sp: ctx.simplePath().simplePathElement() ) {
|
||||
// allow function names of form foo.bar to be located in the registry
|
||||
functionName.append('.').append( visitIdentifier( sp.identifier() ) );
|
||||
|
@ -4474,9 +4498,8 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
final Integer scale = secondArg == null ? null : Integer.valueOf( secondArg.getText() );
|
||||
|
||||
return new SqmCastTarget<>(
|
||||
(ReturnableType<?>)
|
||||
creationContext.getTypeConfiguration()
|
||||
.resolveCastTargetType( targetName ),
|
||||
creationContext.getTypeConfiguration()
|
||||
.resolveCastTargetType( targetName ),
|
||||
//TODO: is there some way to interpret as length vs precision/scale here at this point?
|
||||
length,
|
||||
precision,
|
||||
|
|
|
@ -41,7 +41,6 @@ import org.hibernate.internal.CoreMessageLogger;
|
|||
import org.hibernate.internal.SessionFactoryRegistry;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||
|
@ -468,7 +467,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
|
||||
@Override
|
||||
public <X, T> SqmExpression<X> cast(JpaExpression<T> expression, Class<X> castTargetJavaType) {
|
||||
final BasicDomainType<X> type = getTypeConfiguration().standardBasicTypeForJavaType( castTargetJavaType );
|
||||
final BasicType<X> type = getTypeConfiguration().standardBasicTypeForJavaType( castTargetJavaType );
|
||||
return getFunctionDescriptor( "cast" ).generateSqmExpression(
|
||||
asList( (SqmTypedNode<?>) expression, new SqmCastTarget<>( type, this ) ),
|
||||
type,
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Function;
|
||||
|
@ -323,7 +324,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
|||
* <p>
|
||||
* The type names are not case-sensitive.
|
||||
*/
|
||||
public BasicValuedMapping resolveCastTargetType(String name) {
|
||||
public BasicType<?> resolveCastTargetType(String name) {
|
||||
switch ( name.toLowerCase() ) {
|
||||
case "string": return getBasicTypeForJavaType( String.class );
|
||||
case "character": return getBasicTypeForJavaType( Character.class );
|
||||
|
@ -346,6 +347,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
|||
case "duration": return getBasicTypeForJavaType( Duration.class );
|
||||
case "instant": return getBasicTypeForJavaType( Instant.class );
|
||||
case "binary": return getBasicTypeForJavaType( byte[].class );
|
||||
case "uuid": return getBasicTypeForJavaType( UUID.class );
|
||||
//this one is very fragile ... works well for BIT or BOOLEAN columns only
|
||||
//works OK, I suppose, for integer columns, but not at all for char columns
|
||||
case "boolean": return getBasicTypeForJavaType( Boolean.class );
|
||||
|
@ -353,7 +355,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
|||
case "yesno": return basicTypeRegistry.getRegisteredType( StandardBasicTypes.YES_NO.getName() );
|
||||
case "numericboolean": return basicTypeRegistry.getRegisteredType( StandardBasicTypes.NUMERIC_BOOLEAN.getName() );
|
||||
default: {
|
||||
final BasicType<Object> registeredBasicType = basicTypeRegistry.getRegisteredType( name );
|
||||
final BasicType<?> registeredBasicType = basicTypeRegistry.getRegisteredType( name );
|
||||
if ( registeredBasicType != null ) {
|
||||
return registeredBasicType;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
|
@ -61,7 +62,6 @@ import static org.hamcrest.CoreMatchers.*;
|
|||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.isOneOf;
|
||||
|
||||
import static org.hibernate.cfg.QuerySettings.PORTABLE_INTEGER_DIVISION;
|
||||
import static org.hibernate.testing.orm.domain.gambit.EntityOfBasics.Gender.FEMALE;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
@ -92,6 +92,7 @@ public class FunctionTests {
|
|||
entity.setTheTime( new Time( 20, 10, 8 ) );
|
||||
entity.setTheDuration( Duration.of(3, ChronoUnit.SECONDS).plus( Duration.of(23,ChronoUnit.MILLIS) ) );
|
||||
entity.setTheTimestamp( new Timestamp( 121, 4, 27, 13, 22, 50, 123456789 ) );
|
||||
entity.setTheUuid( UUID.randomUUID() );
|
||||
em.persist(entity);
|
||||
|
||||
EntityOfLists eol = new EntityOfLists(1,"");
|
||||
|
@ -1280,10 +1281,14 @@ public class FunctionTests {
|
|||
session -> {
|
||||
assertThat( session.createQuery("select function('lower','HIBERNATE')", String.class).getSingleResult(),
|
||||
equalTo("hibernate") );
|
||||
assertThat( session.createQuery("select function(lower as String,'HIBERNATE')", String.class).getSingleResult(),
|
||||
equalTo("hibernate") );
|
||||
assertThat( session.createQuery("select 1 where function('lower','HIBERNATE') = 'hibernate'", Integer.class).getSingleResult(),
|
||||
equalTo(1) );
|
||||
assertThat( session.createQuery("select function('current_user')", String.class).getSingleResult().toLowerCase(),
|
||||
isOneOf("hibernate_orm_test", "hibernateormtest", "sa", "hibernateormtest@%", "hibernate_orm_test@%", "root@%") );
|
||||
assertThat( session.createQuery("select function(current_user as String)", String.class).getSingleResult().toLowerCase(),
|
||||
isOneOf("hibernate_orm_test", "hibernateormtest", "sa", "hibernateormtest@%", "hibernate_orm_test@%", "root@%") );
|
||||
assertThat( session.createQuery("select lower(function('current_user'))", String.class).getSingleResult(),
|
||||
isOneOf("hibernate_orm_test", "hibernateormtest", "sa", "hibernateormtest@%", "hibernate_orm_test@%", "root@%") );
|
||||
session.createQuery("select 1 where function('current_user') = 'hibernate_orm_test'", Integer.class).getSingleResultOrNull();
|
||||
|
@ -2268,4 +2273,38 @@ public class FunctionTests {
|
|||
.getSingleResultOrNull());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testColumnFunction(SessionFactoryScope scope) {
|
||||
scope.inTransaction(s -> {
|
||||
assertEquals("the string",
|
||||
s.createSelectionQuery("select column(e.the_column) from EntityOfBasics e", String.class)
|
||||
.getSingleResultOrNull());
|
||||
assertEquals("the string",
|
||||
s.createSelectionQuery("select column(e.'the_column') from EntityOfBasics e", String.class)
|
||||
.getSingleResultOrNull());
|
||||
s.createSelectionQuery("from EntityOfBasics e where column(e.the_column as String) = 'the string'", EntityOfBasics.class)
|
||||
.getSingleResult();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUUIDColumnFunction(SessionFactoryScope scope) {
|
||||
scope.inTransaction(s -> {
|
||||
byte[] bytes = s.createSelectionQuery("select column(e.theuuid as binary) from EntityOfBasics e", byte[].class)
|
||||
.getSingleResultOrNull();
|
||||
UUID uuid = s.createSelectionQuery("select column(e.theuuid as UUID) from EntityOfBasics e", UUID.class)
|
||||
.getSingleResultOrNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test @RequiresDialect(PostgreSQLDialect.class)
|
||||
public void testCtidColumnFunction(SessionFactoryScope scope) {
|
||||
scope.inTransaction(s -> {
|
||||
String string = s.createSelectionQuery("select column(e.ctid as String) from EntityOfBasics e", String.class)
|
||||
.getSingleResultOrNull();
|
||||
byte[] bytes = s.createSelectionQuery("select column(e.ctid as binary) from EntityOfBasics e", byte[].class)
|
||||
.getSingleResultOrNull();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ import java.time.LocalTime;
|
|||
import java.time.OffsetDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
|
@ -68,6 +70,7 @@ public class EntityOfBasics {
|
|||
private Gender convertedGender;
|
||||
private Gender ordinalGender;
|
||||
private Duration theDuration;
|
||||
private UUID theUuid;
|
||||
|
||||
private LocalDateTime theLocalDateTime;
|
||||
private LocalDate theLocalDate;
|
||||
|
@ -77,6 +80,8 @@ public class EntityOfBasics {
|
|||
|
||||
private MutableValue mutableValue;
|
||||
|
||||
private String theField = "the string";
|
||||
|
||||
public EntityOfBasics() {
|
||||
}
|
||||
|
||||
|
@ -272,6 +277,15 @@ public class EntityOfBasics {
|
|||
this.theDuration = theDuration;
|
||||
}
|
||||
|
||||
@Column(name = "theuuid")
|
||||
public UUID getTheUuid() {
|
||||
return theUuid;
|
||||
}
|
||||
|
||||
public void setTheUuid(UUID theUuid) {
|
||||
this.theUuid = theUuid;
|
||||
}
|
||||
|
||||
public Boolean isTheBoolean() {
|
||||
return theBoolean;
|
||||
}
|
||||
|
@ -298,6 +312,15 @@ public class EntityOfBasics {
|
|||
this.theStringBoolean = theStringBoolean;
|
||||
}
|
||||
|
||||
@Column(name = "the_column")
|
||||
public String getTheField() {
|
||||
return theField;
|
||||
}
|
||||
|
||||
public void setTheField(String theField) {
|
||||
this.theField = theField;
|
||||
}
|
||||
|
||||
@Convert( converter = MutableValueConverter.class )
|
||||
public MutableValue getMutableValue() {
|
||||
return mutableValue;
|
||||
|
|
|
@ -135,6 +135,9 @@ public abstract class MockSessionFactory
|
|||
implements SessionFactoryImplementor, QueryEngine, RuntimeModelCreationContext, MetadataBuildingOptions,
|
||||
BootstrapContext, MetadataBuildingContext, FunctionContributions, SessionFactoryOptions, JdbcTypeIndicators {
|
||||
|
||||
private static final BasicTypeImpl<Object> OBJECT_BASIC_TYPE =
|
||||
new BasicTypeImpl<>(new UnknownBasicJavaType<>(Object.class), ObjectJdbcType.INSTANCE);
|
||||
|
||||
// static so other things can get at it
|
||||
// TODO: make a static instance of this whole object instead!
|
||||
static TypeConfiguration typeConfiguration;
|
||||
|
@ -972,7 +975,7 @@ public abstract class MockSessionFactory
|
|||
return (DomainType<?>) elementType;
|
||||
}
|
||||
else {
|
||||
return new BasicTypeImpl<>(new UnknownBasicJavaType<>(Object.class), ObjectJdbcType.INSTANCE);
|
||||
return OBJECT_BASIC_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue