6 - SQM based on JPA type system

This commit is contained in:
Andrea Boriero 2019-07-11 10:53:54 +01:00
parent a769d47a9a
commit f48f486ec6
11 changed files with 355 additions and 301 deletions

View File

@ -22,6 +22,7 @@ import javax.persistence.SqlResultSetMapping;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.cfg.BinderHelper;
import org.hibernate.cfg.QuerySecondPass;
@ -57,145 +58,146 @@ public class ResultsetMappingSecondPass implements QuerySecondPass {
@Override
public void doSecondPass(Map persistentClasses) throws MappingException {
//TODO add parameters checkings
if ( ann == null ) return;
ResultSetMappingDescriptor definition = new ResultSetMappingDescriptor( ann.name() );
LOG.debugf( "Binding result set mapping: %s", definition.getName() );
int entityAliasIndex = 0;
for (EntityResult entity : ann.entities()) {
//TODO parameterize lock mode?
List<FieldResult> properties = new ArrayList<FieldResult>();
List<String> propertyNames = new ArrayList<String>();
for (FieldResult field : entity.fields()) {
//use an ArrayList cause we might have several columns per root property
String name = field.name();
if ( name.indexOf( '.' ) == -1 ) {
//regular property
properties.add( field );
propertyNames.add( name );
}
else {
/**
* Reorder properties
* 1. get the parent property
* 2. list all the properties following the expected one in the parent property
* 3. calculate the lowest index and insert the property
*/
PersistentClass pc = context.getMetadataCollector().getEntityBinding(
entity.entityClass().getName()
);
if ( pc == null ) {
throw new MappingException(
String.format(
Locale.ENGLISH,
"Could not resolve entity [%s] referenced in SqlResultSetMapping [%s]",
entity.entityClass().getName(),
ann.name()
)
);
}
int dotIndex = name.lastIndexOf( '.' );
String reducedName = name.substring( 0, dotIndex );
Iterator parentPropItr = getSubPropertyIterator( pc, reducedName );
List<String> followers = getFollowers( parentPropItr, reducedName, name );
int index = propertyNames.size();
for ( String follower : followers ) {
int currentIndex = getIndexOfFirstMatchingProperty( propertyNames, follower );
index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
}
propertyNames.add( index, name );
properties.add( index, field );
}
}
Set<String> uniqueReturnProperty = new HashSet<String>();
Map<String, ArrayList<String>> propertyResultsTmp = new HashMap<String, ArrayList<String>>();
for ( Object property : properties ) {
final FieldResult propertyresult = ( FieldResult ) property;
final String name = propertyresult.name();
if ( "class".equals( name ) ) {
throw new MappingException(
"class is not a valid property name to use in a @FieldResult, use @Entity(discriminatorColumn) instead"
);
}
if ( uniqueReturnProperty.contains( name ) ) {
throw new MappingException(
"duplicate @FieldResult for property " + name +
" on @Entity " + entity.entityClass().getName() + " in " + ann.name()
);
}
uniqueReturnProperty.add( name );
final String quotingNormalizedColumnName = normalizeColumnQuoting( propertyresult.column() );
String key = StringHelper.root( name );
ArrayList<String> intermediateResults = propertyResultsTmp.get( key );
if ( intermediateResults == null ) {
intermediateResults = new ArrayList<String>();
propertyResultsTmp.put( key, intermediateResults );
}
intermediateResults.add( quotingNormalizedColumnName );
}
Map<String, String[]> propertyResults = new HashMap<String,String[]>();
for ( Map.Entry<String, ArrayList<String>> entry : propertyResultsTmp.entrySet() ) {
propertyResults.put(
entry.getKey(),
entry.getValue().toArray( new String[ entry.getValue().size() ] )
);
}
if ( !BinderHelper.isEmptyAnnotationValue( entity.discriminatorColumn() ) ) {
final String quotingNormalizedName = normalizeColumnQuoting( entity.discriminatorColumn() );
propertyResults.put( "class", new String[] { quotingNormalizedName } );
}
if ( propertyResults.isEmpty() ) {
propertyResults = java.util.Collections.emptyMap();
}
NativeSQLQueryRootReturn result = new NativeSQLQueryRootReturn(
"alias" + entityAliasIndex++,
entity.entityClass().getName(),
propertyResults,
LockMode.READ
);
definition.addQueryReturn( result );
}
for ( ColumnResult column : ann.columns() ) {
definition.addQueryReturn(
new NativeSQLQueryScalarReturn(
normalizeColumnQuoting( column.name() ),
column.type() != null ? context.getMetadataCollector().getTypeResolver().heuristicType( column.type().getName() ) : null
)
);
}
for ( ConstructorResult constructorResult : ann.classes() ) {
List<NativeSQLQueryScalarReturn> columnReturns = new ArrayList<NativeSQLQueryScalarReturn>();
for ( ColumnResult columnResult : constructorResult.columns() ) {
columnReturns.add(
new NativeSQLQueryScalarReturn(
normalizeColumnQuoting( columnResult.name() ),
columnResult.type() != null ? context.getMetadataCollector().getTypeResolver().heuristicType( columnResult.type().getName() ) : null
)
);
}
definition.addQueryReturn(
new NativeSQLQueryConstructorReturn( constructorResult.targetClass(), columnReturns )
);
}
if ( isDefault ) {
context.getMetadataCollector().addDefaultResultSetMapping( definition );
}
else {
context.getMetadataCollector().addResultSetMapping( definition );
}
// if ( ann == null ) return;
// ResultSetMappingDescriptor definition = new ResultSetMappingDescriptor( ann.name() );
// LOG.debugf( "Binding result set mapping: %s", definition.getName() );
//
// int entityAliasIndex = 0;
//
// for (EntityResult entity : ann.entities()) {
// //TODO parameterize lock mode?
// List<FieldResult> properties = new ArrayList<FieldResult>();
// List<String> propertyNames = new ArrayList<String>();
// for (FieldResult field : entity.fields()) {
// //use an ArrayList cause we might have several columns per root property
// String name = field.name();
// if ( name.indexOf( '.' ) == -1 ) {
// //regular property
// properties.add( field );
// propertyNames.add( name );
// }
// else {
// /**
// * Reorder properties
// * 1. get the parent property
// * 2. list all the properties following the expected one in the parent property
// * 3. calculate the lowest index and insert the property
// */
// PersistentClass pc = context.getMetadataCollector().getEntityBinding(
// entity.entityClass().getName()
// );
// if ( pc == null ) {
// throw new MappingException(
// String.format(
// Locale.ENGLISH,
// "Could not resolve entity [%s] referenced in SqlResultSetMapping [%s]",
// entity.entityClass().getName(),
// ann.name()
// )
// );
// }
// int dotIndex = name.lastIndexOf( '.' );
// String reducedName = name.substring( 0, dotIndex );
// Iterator parentPropItr = getSubPropertyIterator( pc, reducedName );
// List<String> followers = getFollowers( parentPropItr, reducedName, name );
//
// int index = propertyNames.size();
// for ( String follower : followers ) {
// int currentIndex = getIndexOfFirstMatchingProperty( propertyNames, follower );
// index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
// }
// propertyNames.add( index, name );
// properties.add( index, field );
// }
// }
//
// Set<String> uniqueReturnProperty = new HashSet<String>();
// Map<String, ArrayList<String>> propertyResultsTmp = new HashMap<String, ArrayList<String>>();
// for ( Object property : properties ) {
// final FieldResult propertyresult = ( FieldResult ) property;
// final String name = propertyresult.name();
// if ( "class".equals( name ) ) {
// throw new MappingException(
// "class is not a valid property name to use in a @FieldResult, use @Entity(discriminatorColumn) instead"
// );
// }
//
// if ( uniqueReturnProperty.contains( name ) ) {
// throw new MappingException(
// "duplicate @FieldResult for property " + name +
// " on @Entity " + entity.entityClass().getName() + " in " + ann.name()
// );
// }
// uniqueReturnProperty.add( name );
//
// final String quotingNormalizedColumnName = normalizeColumnQuoting( propertyresult.column() );
//
// String key = StringHelper.root( name );
// ArrayList<String> intermediateResults = propertyResultsTmp.get( key );
// if ( intermediateResults == null ) {
// intermediateResults = new ArrayList<String>();
// propertyResultsTmp.put( key, intermediateResults );
// }
// intermediateResults.add( quotingNormalizedColumnName );
// }
//
// Map<String, String[]> propertyResults = new HashMap<String,String[]>();
// for ( Map.Entry<String, ArrayList<String>> entry : propertyResultsTmp.entrySet() ) {
// propertyResults.put(
// entry.getKey(),
// entry.getValue().toArray( new String[ entry.getValue().size() ] )
// );
// }
//
// if ( !BinderHelper.isEmptyAnnotationValue( entity.discriminatorColumn() ) ) {
// final String quotingNormalizedName = normalizeColumnQuoting( entity.discriminatorColumn() );
// propertyResults.put( "class", new String[] { quotingNormalizedName } );
// }
//
// if ( propertyResults.isEmpty() ) {
// propertyResults = java.util.Collections.emptyMap();
// }
//
// NativeSQLQueryRootReturn result = new NativeSQLQueryRootReturn(
// "alias" + entityAliasIndex++,
// entity.entityClass().getName(),
// propertyResults,
// LockMode.READ
// );
// definition.addQueryReturn( result );
// }
//
// for ( ColumnResult column : ann.columns() ) {
// definition.addQueryReturn(
// new NativeSQLQueryScalarReturn(
// normalizeColumnQuoting( column.name() ),
// column.type() != null ? context.getMetadataCollector().getTypeResolver().heuristicType( column.type().getName() ) : null
// )
// );
// }
//
// for ( ConstructorResult constructorResult : ann.classes() ) {
// List<NativeSQLQueryScalarReturn> columnReturns = new ArrayList<NativeSQLQueryScalarReturn>();
// for ( ColumnResult columnResult : constructorResult.columns() ) {
// columnReturns.add(
// new NativeSQLQueryScalarReturn(
// normalizeColumnQuoting( columnResult.name() ),
// columnResult.type() != null ? context.getMetadataCollector().getTypeResolver().heuristicType( columnResult.type().getName() ) : null
// )
// );
// }
// definition.addQueryReturn(
// new NativeSQLQueryConstructorReturn( constructorResult.targetClass(), columnReturns )
// );
// }
//
// if ( isDefault ) {
// context.getMetadataCollector().addDefaultResultSetMapping( definition );
// }
// else {
// context.getMetadataCollector().addResultSetMapping( definition );
// }
throw new NotYetImplementedFor6Exception( getClass() );
}
private String normalizeColumnQuoting(String name) {

View File

@ -7,6 +7,7 @@
package org.hibernate.engine.query.spi;
import org.hibernate.Incubating;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.type.Type;
/**
@ -40,4 +41,9 @@ public class OrdinalParameterDescriptor extends AbstractParameterDescriptor {
public int getValuePosition() {
return valuePosition;
}
@Override
public boolean allowsMultiValuedBinding() {
throw new NotYetImplementedFor6Exception( getClass() );
}
}

View File

@ -26,7 +26,5 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@Incubating
public interface AllowableParameterType<J> extends Writeable {
default JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor(){
throw new NotYetImplementedFor6Exception( getClass() );
}
JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor();
}

View File

@ -11,6 +11,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@ -229,6 +230,9 @@ public abstract class AbstractCollectionPersister
private Map collectionPropertyColumnAliases = new HashMap();
private final Comparator comparator;
public AbstractCollectionPersister(
Collection collectionBinding,
CollectionDataAccess cacheAccessStrategy,
@ -609,9 +613,16 @@ public abstract class AbstractCollectionPersister
// manyToManyOrderByTranslation = null;
}
comparator = collectionBinding.getComparator();
initCollectionPropertyMap();
}
@Override
public Comparator<?> getSortingComparator() {
return comparator;
}
protected String determineTableName(Table table, JdbcEnvironment jdbcEnvironment) {
if ( table.getSubselect() != null ) {
return "( " + table.getSubselect() + " )";

View File

@ -9,6 +9,7 @@ package org.hibernate.persister.collection;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Comparator;
import java.util.Map;
import org.hibernate.HibernateException;
@ -20,6 +21,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.walking.spi.CollectionDefinition;
@ -320,4 +322,14 @@ public interface CollectionPersister extends CollectionDefinition {
* @return the name of the property this collection is mapped by
*/
String getMappedByProperty();
/**
* For sorted collections, the comparator to use. Non-parameterized
* because for SORTED_SET the elements are compared but for SORTED_MAP the
* keys are compared
*
* @see CollectionClassification#SORTED_MAP
* @see CollectionClassification#SORTED_SET
*/
Comparator<?> getSortingComparator();
}

View File

@ -28,6 +28,7 @@ import javax.persistence.TemporalType;
import javax.persistence.TransactionRequiredException;
import org.hibernate.HibernateException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.ScrollMode;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -383,50 +384,51 @@ public class ProcedureCallImpl<R>
// both: (1) add the `? = ` part and also (2) register a REFCURSOR parameter for DBs (Oracle, PGSQL) that
// need it.
final String call = getSession().getJdbcServices().getJdbcEnvironment().getDialect().getCallableStatementSupport().renderCallableStatement(
procedureName,
getParameterMetadata(),
paramBindings,
getSession()
);
LOG.debugf( "Preparing procedure call : %s", call );
final CallableStatement statement = (CallableStatement) getSession()
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( call, true );
// prepare parameters
getParameterMetadata().visitRegistrations(
new Consumer<QueryParameter<?>>() {
int i = 1;
@Override
public void accept(QueryParameter queryParameter) {
try {
final ProcedureParameterImplementor registration = (ProcedureParameterImplementor) queryParameter;
registration.prepare( statement, i, ProcedureCallImpl.this );
if ( registration.getMode() == ParameterMode.REF_CURSOR ) {
i++;
}
else {
i += registration.getSqlTypes().length;
}
}
catch (SQLException e) {
throw getSession().getJdbcServices().getSqlExceptionHelper().convert(
e,
"Error preparing registered callable parameter",
getProcedureName()
);
}
}
}
);
return new ProcedureOutputsImpl( this, statement );
// final String call = getSession().getJdbcServices().getJdbcEnvironment().getDialect().getCallableStatementSupport().renderCallableStatement(
// procedureName,
// getParameterMetadata(),
// paramBindings,
// getSession()
// );
//
// LOG.debugf( "Preparing procedure call : %s", call );
// final CallableStatement statement = (CallableStatement) getSession()
// .getJdbcCoordinator()
// .getStatementPreparer()
// .prepareStatement( call, true );
//
//
// // prepare parameters
//
// getParameterMetadata().visitRegistrations(
// new Consumer<QueryParameter<?>>() {
// int i = 1;
//
// @Override
// public void accept(QueryParameter queryParameter) {
// try {
// final ProcedureParameterImplementor registration = (ProcedureParameterImplementor) queryParameter;
// registration.prepare( statement, i, ProcedureCallImpl.this );
// if ( registration.getMode() == ParameterMode.REF_CURSOR ) {
// i++;
// }
// else {
// i += registration.getSqlTypes().length;
// }
// }
// catch (SQLException e) {
// throw getSession().getJdbcServices().getSqlExceptionHelper().convert(
// e,
// "Error preparing registered callable parameter",
// getProcedureName()
// );
// }
// }
// }
// );
//
// return new ProcedureOutputsImpl( this, statement );
throw new NotYetImplementedFor6Exception( getClass() );
}
@Override

View File

@ -11,6 +11,7 @@ import java.sql.SQLException;
import java.util.Objects;
import javax.persistence.ParameterMode;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.jdbc.cursor.spi.RefCursorSupport;
import org.hibernate.metamodel.model.domain.AllowableParameterType;
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
@ -127,117 +128,118 @@ public class ProcedureParameterImpl<T> extends AbstractQueryParameter<T> impleme
CallableStatement statement,
int startIndex,
ProcedureCallImplementor<?> procedureCall) throws SQLException {
final QueryParameterBinding<?> binding = procedureCall.getParameterBindings().getBinding( this );
// initially set up the Type we will use for binding as the explicit type.
AllowableParameterType typeToUse = getHibernateType();
// however, for Calendar binding with an explicit TemporalType we may need to adjust this...
if ( binding != null && binding.getExplicitTemporalPrecision() != null ) {
typeToUse = ( (AllowableTemporalParameterType) typeToUse ).resolveTemporalPrecision(
binding.getExplicitTemporalPrecision(),
procedureCall.getSession().getFactory().getTypeConfiguration()
);
}
this.startIndex = startIndex;
if ( mode == ParameterMode.IN || mode == ParameterMode.INOUT || mode == ParameterMode.OUT ) {
if ( mode == ParameterMode.INOUT || mode == ParameterMode.OUT ) {
if ( sqlTypesToUse.length > 1 ) {
// there is more than one column involved; see if the Hibernate Type can handle
// multi-param extraction...
final boolean canHandleMultiParamExtraction =
ProcedureParameterExtractionAware.class.isInstance( typeToUse )
&& ( (ProcedureParameterExtractionAware) typeToUse ).canDoExtraction();
if ( ! canHandleMultiParamExtraction ) {
// it cannot...
throw new UnsupportedOperationException(
"Type [" + typeToUse + "] does support multi-parameter value extraction"
);
}
}
// TODO: sqlTypesToUse.length > 1 does not seem to have a working use case (HHH-10769).
// The idea is that an embeddable/custom type can have more than one column values
// that correspond with embeddable/custom attribute value. This does not seem to
// be working yet. For now, if sqlTypesToUse.length > 1, then register
// the out parameters by position (since we only have one name).
// This will cause a failure if there are other parameters bound by
// name and the dialect does not support "mixed" named/positional parameters;
// e.g., Oracle.
if ( sqlTypesToUse.length == 1 &&
procedureCall.getParameterStrategy() == ParameterStrategy.NAMED &&
canDoNameParameterBinding( typeToUse ) ) {
statement.registerOutParameter( getName(), sqlTypesToUse[0] );
}
else {
for ( int i = 0; i < sqlTypesToUse.length; i++ ) {
statement.registerOutParameter( startIndex + i, sqlTypesToUse[i] );
}
}
}
if ( mode == ParameterMode.INOUT || mode == ParameterMode.IN ) {
if ( binding == null || binding.getBindValue() == null ) {
// the user did not binding a value to the parameter being processed. This is the condition
// defined by `passNulls` and that value controls what happens here. If `passNulls` is
// {@code true} we will binding the NULL value into the statement; if `passNulls` is
// {@code false} we will not.
//
// Unfortunately there is not a way to reliably know through JDBC metadata whether a procedure
// parameter defines a default value. Deferring to that information would be the best option
if ( isPassNullsEnabled() ) {
log.debugf(
"Stored procedure [%s] IN/INOUT parameter [%s] not bound and `passNulls` was set to true; binding NULL",
procedureCall.getProcedureName(),
this
);
if ( procedureCall.getParameterStrategy() == ParameterStrategy.NAMED && canDoNameParameterBinding( typeToUse ) ) {
((ProcedureParameterNamedBinder) typeToUse).nullSafeSet(
statement,
null,
this.getName(),
procedureCall.getSession()
);
}
else {
typeToUse.nullSafeSet( statement, null, startIndex, procedureCall.getSession() );
}
}
else {
log.debugf(
"Stored procedure [%s] IN/INOUT parameter [%s] not bound and `passNulls` was set to false; assuming procedure defines default value",
procedureCall.getProcedureName(),
this
);
}
}
else {
if ( procedureCall.getParameterStrategy() == ParameterStrategy.NAMED && canDoNameParameterBinding( typeToUse ) ) {
((ProcedureParameterNamedBinder) typeToUse).nullSafeSet(
statement,
binding.getBindValue(),
this.getName(),
procedureCall.getSession()
);
}
else {
typeToUse.nullSafeSet( statement, binding.getBindValue(), startIndex, procedureCall.getSession() );
}
}
}
}
else {
// we have a REF_CURSOR type param
if ( procedureCall.getParameterStrategy() == ParameterStrategy.NAMED ) {
procedureCall.getSession().getFactory().getServiceRegistry()
.getService( RefCursorSupport.class )
.registerRefCursorParameter( statement, getName() );
}
else {
procedureCall.getSession().getFactory().getServiceRegistry()
.getService( RefCursorSupport.class )
.registerRefCursorParameter( statement, startIndex );
}
}
throw new NotYetImplementedFor6Exception( getClass() );
// final QueryParameterBinding<?> binding = procedureCall.getParameterBindings().getBinding( this );
//
// // initially set up the Type we will use for binding as the explicit type.
// AllowableParameterType typeToUse = getHibernateType();
//
// // however, for Calendar binding with an explicit TemporalType we may need to adjust this...
// if ( binding != null && binding.getExplicitTemporalPrecision() != null ) {
// typeToUse = ( (AllowableTemporalParameterType) typeToUse ).resolveTemporalPrecision(
// binding.getExplicitTemporalPrecision(),
// procedureCall.getSession().getFactory().getTypeConfiguration()
// );
// }
//
// this.startIndex = startIndex;
// if ( mode == ParameterMode.IN || mode == ParameterMode.INOUT || mode == ParameterMode.OUT ) {
// if ( mode == ParameterMode.INOUT || mode == ParameterMode.OUT ) {
// if ( sqlTypesToUse.length > 1 ) {
// // there is more than one column involved; see if the Hibernate Type can handle
// // multi-param extraction...
// final boolean canHandleMultiParamExtraction =
// ProcedureParameterExtractionAware.class.isInstance( typeToUse )
// && ( (ProcedureParameterExtractionAware) typeToUse ).canDoExtraction();
// if ( ! canHandleMultiParamExtraction ) {
// // it cannot...
// throw new UnsupportedOperationException(
// "Type [" + typeToUse + "] does support multi-parameter value extraction"
// );
// }
// }
// // TODO: sqlTypesToUse.length > 1 does not seem to have a working use case (HHH-10769).
// // The idea is that an embeddable/custom type can have more than one column values
// // that correspond with embeddable/custom attribute value. This does not seem to
// // be working yet. For now, if sqlTypesToUse.length > 1, then register
// // the out parameters by position (since we only have one name).
// // This will cause a failure if there are other parameters bound by
// // name and the dialect does not support "mixed" named/positional parameters;
// // e.g., Oracle.
// if ( sqlTypesToUse.length == 1 &&
// procedureCall.getParameterStrategy() == ParameterStrategy.NAMED &&
// canDoNameParameterBinding( typeToUse ) ) {
// statement.registerOutParameter( getName(), sqlTypesToUse[0] );
// }
// else {
// for ( int i = 0; i < sqlTypesToUse.length; i++ ) {
// statement.registerOutParameter( startIndex + i, sqlTypesToUse[i] );
// }
// }
// }
//
// if ( mode == ParameterMode.INOUT || mode == ParameterMode.IN ) {
// if ( binding == null || binding.getBindValue() == null ) {
// // the user did not binding a value to the parameter being processed. This is the condition
// // defined by `passNulls` and that value controls what happens here. If `passNulls` is
// // {@code true} we will binding the NULL value into the statement; if `passNulls` is
// // {@code false} we will not.
// //
// // Unfortunately there is not a way to reliably know through JDBC metadata whether a procedure
// // parameter defines a default value. Deferring to that information would be the best option
// if ( isPassNullsEnabled() ) {
// log.debugf(
// "Stored procedure [%s] IN/INOUT parameter [%s] not bound and `passNulls` was set to true; binding NULL",
// procedureCall.getProcedureName(),
// this
// );
// if ( procedureCall.getParameterStrategy() == ParameterStrategy.NAMED && canDoNameParameterBinding( typeToUse ) ) {
// ((ProcedureParameterNamedBinder) typeToUse).nullSafeSet(
// statement,
// null,
// this.getName(),
// procedureCall.getSession()
// );
// }
// else {
// typeToUse.nullSafeSet( statement, null, startIndex, procedureCall.getSession() );
// }
// }
// else {
// log.debugf(
// "Stored procedure [%s] IN/INOUT parameter [%s] not bound and `passNulls` was set to false; assuming procedure defines default value",
// procedureCall.getProcedureName(),
// this
// );
// }
// }
// else {
// if ( procedureCall.getParameterStrategy() == ParameterStrategy.NAMED && canDoNameParameterBinding( typeToUse ) ) {
// ((ProcedureParameterNamedBinder) typeToUse).nullSafeSet(
// statement,
// binding.getBindValue(),
// this.getName(),
// procedureCall.getSession()
// );
// }
// else {
// typeToUse.nullSafeSet( statement, binding.getBindValue(), startIndex, procedureCall.getSession() );
// }
// }
// }
// }
// else {
// // we have a REF_CURSOR type param
// if ( procedureCall.getParameterStrategy() == ParameterStrategy.NAMED ) {
// procedureCall.getSession().getFactory().getServiceRegistry()
// .getService( RefCursorSupport.class )
// .registerRefCursorParameter( statement, getName() );
// }
// else {
// procedureCall.getSession().getFactory().getServiceRegistry()
// .getService( RefCursorSupport.class )
// .registerRefCursorParameter( statement, startIndex );
// }
// }
}
}

View File

@ -130,7 +130,7 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T> {
//noinspection unchecked
this.bindType = (AllowableParameterType) BindingTypeHelper.INSTANCE.resolveDateTemporalTypeVariant(
getBindType().getJavaType(),
getBindType().getExpressableJavaTypeDescriptor().getJavaType(),
getBindType()
);

View File

@ -90,7 +90,7 @@ public interface ResultSetMappingDescriptor {
/**
* temporary so I can call externally
*/
public interface QueryResultDefinition {
interface QueryResultDefinition {
// what args?
QueryResultBuilder resolve();
}

View File

@ -16,7 +16,7 @@ import org.hibernate.internal.util.collections.StandardStack;
/**
* Maintains a Stack of processing state related to performing load operations.
* The state is defined by {@link JdbcValuesSourceProcessingState} which
* The sCollectionLoadContexttate is defined by {@link JdbcValuesSourceProcessingState} which
* encapsulates the data to be processed by the load whether the data comes from
* a ResultSet or second-level cache hit.
*

View File

@ -30,6 +30,7 @@ import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.MutableEntityEntryFactory;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.EntityEntryFactory;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.spi.ValueInclusion;
@ -628,6 +629,21 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
public boolean canUseReferenceCacheEntries() {
return false;
}
@Override
public boolean isAffectedByEnabledFilters(LoadQueryInfluencers influencers) {
return false;
}
@Override
public boolean isAffectedByEntityGraph(LoadQueryInfluencers influencers) {
return false;
}
@Override
public boolean isAffectedByEnabledFetchProfiles(LoadQueryInfluencers influencers) {
return false;
}
}
public static class NoopCollectionPersister implements CollectionPersister {
@ -877,6 +893,11 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
return null;
}
@Override
public Comparator<?> getSortingComparator() {
return null;
}
@Override
public void processQueuedOps(PersistentCollection collection, Serializable key, SharedSessionContractImplementor session)
throws HibernateException {