HHH-15818 - Drop PropertyMapping in favor of new mapping-model

This commit is contained in:
Steve Ebersole 2022-12-05 18:45:56 -06:00
parent 3d72eabf6c
commit 33c00d78c3
10 changed files with 141 additions and 77 deletions

View File

@ -75,7 +75,6 @@ public void checkId(Object object, EntityPersister persister, Object id, Session
return; return;
} }
if ( persister.canExtractIdOutOfEntity() ) {
final Object oid = persister.getIdentifier( object, session ); final Object oid = persister.getIdentifier( object, session );
if ( id == null ) { if ( id == null ) {
@ -88,7 +87,6 @@ public void checkId(Object object, EntityPersister persister, Object id, Session
+ " was altered from " + oid + " to " + id ); + " was altered from " + oid + " to " + id );
} }
} }
}
private void checkNaturalId( private void checkNaturalId(
EntityPersister persister, EntityPersister persister,

View File

@ -372,6 +372,7 @@ else if ( bootModelValue instanceof OneToMany ) {
while ( ( dotIndex = referencedPropertyName.indexOf( '.', dotIndex + 1 ) ) != -1 ) { while ( ( dotIndex = referencedPropertyName.indexOf( '.', dotIndex + 1 ) ) != -1 ) {
targetKeyPropertyNames.add( referencedPropertyName.substring( 0, dotIndex ) ); targetKeyPropertyNames.add( referencedPropertyName.substring( 0, dotIndex ) );
} }
// todo (PropertyMapping) : the problem here is timing. this needs to be delayed.
final Type propertyType = ( (PropertyMapping) elementTypeDescriptor.getEntityPersister() ) final Type propertyType = ( (PropertyMapping) elementTypeDescriptor.getEntityPersister() )
.toType( referencedPropertyName ); .toType( referencedPropertyName );
ToOneAttributeMapping.addPrefixedPropertyNames( ToOneAttributeMapping.addPrefixedPropertyNames(

View File

@ -1173,6 +1173,7 @@ public boolean hasOrphanDelete() {
@Override @Override
public Type toType(String propertyName) throws QueryException { public Type toType(String propertyName) throws QueryException {
// todo (PropertyMapping) : simple delegation (aka, easy to remove)
if ( "index".equals( propertyName ) ) { if ( "index".equals( propertyName ) ) {
return indexType; return indexType;
} }
@ -1308,6 +1309,7 @@ public String getManyToManyFilterFragment(TableGroup tableGroup, Map<String, Fil
@Override @Override
public String[] toColumns(String propertyName) throws QueryException { public String[] toColumns(String propertyName) throws QueryException {
// todo (PropertyMapping) : simple delegation (aka, easy to remove)
if ( "index".equals( propertyName ) ) { if ( "index".equals( propertyName ) ) {
if ( indexFragments == null ) { if ( indexFragments == null ) {
String[] tmp = new String[indexColumnNames.length]; String[] tmp = new String[indexColumnNames.length];

View File

@ -6,6 +6,7 @@
*/ */
package org.hibernate.persister.collection; package org.hibernate.persister.collection;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.Remove;
import org.hibernate.boot.Metadata; import org.hibernate.boot.Metadata;
import org.hibernate.persister.entity.AbstractPropertyMapping; import org.hibernate.persister.entity.AbstractPropertyMapping;
import org.hibernate.type.CompositeType; import org.hibernate.type.CompositeType;
@ -14,6 +15,8 @@
/** /**
* @author Gavin King * @author Gavin King
*/ */
@Deprecated( since = "6", forRemoval = true )
@Remove()
public class CompositeElementPropertyMapping extends AbstractPropertyMapping { public class CompositeElementPropertyMapping extends AbstractPropertyMapping {
private final CompositeType compositeType; private final CompositeType compositeType;

View File

@ -7,12 +7,15 @@
package org.hibernate.persister.collection; package org.hibernate.persister.collection;
import org.hibernate.QueryException; import org.hibernate.QueryException;
import org.hibernate.Remove;
import org.hibernate.persister.entity.PropertyMapping; import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.type.Type; import org.hibernate.type.Type;
/** /**
* @author Gavin King * @author Gavin King
*/ */
@Deprecated( since = "6", forRemoval = true )
@Remove()
public class ElementPropertyMapping implements PropertyMapping { public class ElementPropertyMapping implements PropertyMapping {
private final String[] elementColumns; private final String[] elementColumns;

View File

@ -40,6 +40,7 @@
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.QueryException; import org.hibernate.QueryException;
import org.hibernate.Remove; import org.hibernate.Remove;
import org.hibernate.StaleObjectStateException; import org.hibernate.StaleObjectStateException;
@ -2131,6 +2132,7 @@ public String[] toColumns(String propertyName) throws QueryException {
*/ */
@Override @Override
public Type toType(String propertyName) throws QueryException { public Type toType(String propertyName) throws QueryException {
// todo (PropertyMapping) : simple delegation (aka, easy to remove)
return propertyMapping.toType( propertyName ); return propertyMapping.toType( propertyName );
} }
@ -2159,29 +2161,31 @@ public String[] getPropertyColumnNames(String propertyName) {
*/ */
@Override @Override
public int getSubclassPropertyTableNumber(String propertyPath) { public int getSubclassPropertyTableNumber(String propertyPath) {
String rootPropertyName = StringHelper.root( propertyPath ); // todo (PropertyMapping) : clean this up
Type type = propertyMapping.toType( rootPropertyName ); throw new NotYetImplementedFor6Exception( getClass() );
if ( type.isAssociationType() ) { // String rootPropertyName = StringHelper.root( propertyPath );
AssociationType assocType = (AssociationType) type; // Type type = propertyMapping.toType( rootPropertyName );
if ( assocType.useLHSPrimaryKey() ) { // if ( type.isAssociationType() ) {
// performance op to avoid the array search // AssociationType assocType = (AssociationType) type;
return 0; // if ( assocType.useLHSPrimaryKey() ) {
} // // performance op to avoid the array search
else if ( type.isCollectionType() ) { // return 0;
// properly handle property-ref-based associations // }
rootPropertyName = assocType.getLHSPropertyName(); // else if ( type.isCollectionType() ) {
} // // properly handle property-ref-based associations
} // rootPropertyName = assocType.getLHSPropertyName();
//Enable for HHH-440, which we don't like: // }
/*if ( type.isComponentType() && !propertyName.equals(rootPropertyName) ) { // }
String unrooted = StringHelper.unroot(propertyName); // //Enable for HHH-440, which we don't like:
int idx = ArrayHelper.indexOf( getSubclassColumnClosure(), unrooted ); // /*if ( type.isComponentType() && !propertyName.equals(rootPropertyName) ) {
if ( idx != -1 ) { // String unrooted = StringHelper.unroot(propertyName);
return getSubclassColumnTableNumberClosure()[idx]; // int idx = ArrayHelper.indexOf( getSubclassColumnClosure(), unrooted );
} // if ( idx != -1 ) {
}*/ // return getSubclassColumnTableNumberClosure()[idx];
int index = ArrayHelper.indexOf( getSubclassPropertyNameClosure(), rootPropertyName ); //TODO: optimize this better! // }
return index == -1 ? 0 : getSubclassPropertyTableNumber( index ); // }*/
// int index = ArrayHelper.indexOf( getSubclassPropertyNameClosure(), rootPropertyName ); //TODO: optimize this better!
// return index == -1 ? 0 : getSubclassPropertyTableNumber( index );
} }
@Override @Override
@ -3766,7 +3770,7 @@ private void handleNaturalIdReattachment(Object entity, SharedSessionContractImp
@Override @Override
public Boolean isTransient(Object entity, SharedSessionContractImplementor session) throws HibernateException { public Boolean isTransient(Object entity, SharedSessionContractImplementor session) throws HibernateException {
final Object id = canExtractIdOutOfEntity() ? getIdentifier(entity, session) : null; final Object id = getIdentifier(entity, session);
// we *always* assume an instance with a null // we *always* assume an instance with a null
// identifier or no identifier property is unsaved! // identifier or no identifier property is unsaved!
if ( id == null ) { if ( id == null ) {
@ -3869,13 +3873,6 @@ public boolean isExplicitPolymorphism() {
return entityMetamodel.isExplicitPolymorphism(); return entityMetamodel.isExplicitPolymorphism();
} }
@Override
public boolean canExtractIdOutOfEntity() {
return hasIdentifierProperty()
|| entityMetamodel.getIdentifierProperty().isEmbedded()
|| entityMetamodel.getIdentifierProperty().hasIdentifierMapper();
}
@Override @Override
public String[] getKeyColumnNames() { public String[] getKeyColumnNames() {
return getIdentifierColumnNames(); return getIdentifierColumnNames();
@ -3913,6 +3910,7 @@ public boolean consumesCollectionAlias() {
*/ */
@Override @Override
public Type getPropertyType(String propertyName) throws MappingException { public Type getPropertyType(String propertyName) throws MappingException {
// todo (PropertyMapping) : caller also deprecated (aka, easy to remove)
return propertyMapping.toType( propertyName ); return propertyMapping.toType( propertyName );
} }

View File

@ -13,6 +13,7 @@
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.QueryException; import org.hibernate.QueryException;
import org.hibernate.Remove;
import org.hibernate.boot.Metadata; import org.hibernate.boot.Metadata;
import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.spi.Mapping; import org.hibernate.engine.spi.Mapping;
@ -38,6 +39,8 @@
* *
* @author Gavin King * @author Gavin King
*/ */
@Deprecated( since = "6", forRemoval = true )
@Remove()
public abstract class AbstractPropertyMapping implements PropertyMapping { public abstract class AbstractPropertyMapping implements PropertyMapping {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractPropertyMapping.class ); private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractPropertyMapping.class );

View File

@ -349,7 +349,10 @@ default boolean hasOwnedCollections() {
* @return The type. * @return The type.
* @throws MappingException Typically indicates an unknown * @throws MappingException Typically indicates an unknown
* property name. * property name.
*
* @deprecated See {@linkplain #findAttributeMapping(String)}
*/ */
@Deprecated( since = "6", forRemoval = true )
Type getPropertyType(String propertyName) throws MappingException; Type getPropertyType(String propertyName) throws MappingException;
/** /**
@ -394,7 +397,10 @@ default boolean hasOwnedCollections() {
* @return True if either (1) {@link #hasIdentifierProperty()} or * @return True if either (1) {@link #hasIdentifierProperty()} or
* (2) the identifier is an embedded composite identifier; false otherwise. * (2) the identifier is an embedded composite identifier; false otherwise.
*/ */
boolean canExtractIdOutOfEntity(); @Deprecated(since = "6")
default boolean canExtractIdOutOfEntity() {
return true;
}
/** /**
* Determine whether optimistic locking by column is enabled for this * Determine whether optimistic locking by column is enabled for this

View File

@ -27,9 +27,6 @@
import org.hibernate.proxy.LazyInitializer; import org.hibernate.proxy.LazyInitializer;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
/** /**
* Base for types which map associations to persistent entities. * Base for types which map associations to persistent entities.
* *
@ -318,11 +315,7 @@ public Object replace(
@Override @Override
public int getHashCode(Object x, SessionFactoryImplementor factory) { public int getHashCode(Object x, SessionFactoryImplementor factory) {
EntityPersister persister = getAssociatedEntityPersister( factory ); final EntityPersister persister = getAssociatedEntityPersister( factory );
if ( !persister.canExtractIdOutOfEntity() ) {
return super.getHashCode( x );
}
final Object id; final Object id;
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( x ); final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( x );
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
@ -347,11 +340,7 @@ public boolean isEqual(Object x, Object y, SessionFactoryImplementor factory) {
return x == y; return x == y;
} }
EntityPersister persister = getAssociatedEntityPersister( factory ); final EntityPersister persister = getAssociatedEntityPersister( factory );
if ( !persister.canExtractIdOutOfEntity() ) {
return super.isEqual( x, y );
}
final Class<?> mappedClass = persister.getMappedClass(); final Class<?> mappedClass = persister.getMappedClass();
Object xid; Object xid;
final LazyInitializer lazyInitializerX = HibernateProxy.extractLazyInitializer( x ); final LazyInitializer lazyInitializerX = HibernateProxy.extractLazyInitializer( x );

View File

@ -6,9 +6,6 @@
*/ */
package org.hibernate.envers.strategy.internal; package org.hibernate.envers.strategy.internal;
import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS;
import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
@ -36,12 +33,15 @@
import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData;
import org.hibernate.envers.internal.revisioninfo.RevisionInfoNumberReader; import org.hibernate.envers.internal.revisioninfo.RevisionInfoNumberReader;
import org.hibernate.envers.internal.synchronization.SessionCacheCleaner; import org.hibernate.envers.internal.synchronization.SessionCacheCleaner;
import org.hibernate.envers.internal.tools.MutableInteger;
import org.hibernate.envers.internal.tools.query.Parameters; import org.hibernate.envers.internal.tools.query.Parameters;
import org.hibernate.envers.internal.tools.query.QueryBuilder; import org.hibernate.envers.internal.tools.query.QueryBuilder;
import org.hibernate.envers.strategy.AuditStrategy; import org.hibernate.envers.strategy.AuditStrategy;
import org.hibernate.envers.strategy.spi.AuditStrategyContext; import org.hibernate.envers.strategy.spi.AuditStrategyContext;
import org.hibernate.envers.strategy.spi.MappingContext; import org.hibernate.envers.strategy.spi.MappingContext;
import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventSource;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.persister.entity.JoinedSubclassEntityPersister; import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
import org.hibernate.persister.entity.Queryable; import org.hibernate.persister.entity.Queryable;
import org.hibernate.persister.entity.UnionSubclassEntityPersister; import org.hibernate.persister.entity.UnionSubclassEntityPersister;
@ -54,6 +54,9 @@
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS;
import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER;
/** /**
* An audit strategy implementation that persists and fetches audit information using a validity * An audit strategy implementation that persists and fetches audit information using a validity
* algorithm, based on the start-revision and end-revision of a row in the audit table schema. * algorithm, based on the start-revision and end-revision of a row in the audit table schema.
@ -548,7 +551,6 @@ private UpdateContext getUpdateContext(
final Queryable revisionEntity = getQueryable( configuration.getRevisionInfo().getRevisionInfoEntityName(), session ); final Queryable revisionEntity = getQueryable( configuration.getRevisionInfo().getRevisionInfoEntityName(), session );
final Number revisionNumber = getRevisionNumber( configuration, revision ); final Number revisionNumber = getRevisionNumber( configuration, revision );
final Type revisionNumberType = revisionEntity.getIdentifierType();
// The expected SQL is an update statement as follows: // The expected SQL is an update statement as follows:
// UPDATE audited_entity SET REVEND = ? [, REVEND_TSTMP = ?] WHERE (entity_id) = ? AND REV <> ? AND REVEND is null // UPDATE audited_entity SET REVEND = ? [, REVEND_TSTMP = ?] WHERE (entity_id) = ? AND REV <> ? AND REVEND is null
@ -556,30 +558,34 @@ private UpdateContext getUpdateContext(
context.setTableName( getUpdateTableName( rootEntity, rootAuditEntity, auditEntity ) ); context.setTableName( getUpdateTableName( rootEntity, rootAuditEntity, auditEntity ) );
// Apply "SET REVEND = ?" portion of the SQL // Apply "SET REVEND = ?" portion of the SQL
final String revEndColumnName = configuration.getRevisionEndFieldName(); final String revEndAttributeName = configuration.getRevisionEndFieldName();
context.addColumn( rootAuditEntity.toColumns( revEndColumnName )[ 0 ] ); final String revEndColumnName = rootAuditEntity.findAttributeMapping( revEndAttributeName )
context.bind( revisionNumber, revisionNumberType ); .getSelectable( 0 )
.getSelectionExpression();
context.addColumn( revEndColumnName );
context.bind( revisionNumber, revisionEntity.getIdentifierMapping() );
if ( configuration.isRevisionEndTimestampEnabled() ) { if ( configuration.isRevisionEndTimestampEnabled() ) {
final String revEndTimestampColumnName = configuration.getRevisionEndTimestampFieldName();
final Type revEndTimestampType = rootAuditEntity.getPropertyType( revEndTimestampColumnName );
final Object revisionTimestamp = revisionTimestampGetter.get( revision ); final Object revisionTimestamp = revisionTimestampGetter.get( revision );
final String revEndTimestampAttributeName = configuration.getRevisionEndTimestampFieldName();
final AttributeMapping revEndTimestampAttributeMapping = rootAuditEntity.findAttributeMapping( revEndTimestampAttributeName );
// Apply optional "[, REVEND_TSTMP = ?]" portion of the SQL // Apply optional "[, REVEND_TSTMP = ?]" portion of the SQL
context.addColumn( rootAuditEntity.toColumns( revEndTimestampColumnName )[ 0 ] ); context.addColumn( revEndTimestampAttributeMapping.getSelectable( 0 ).getSelectionExpression() );
context.bind( getRevEndTimestampValue( configuration, revisionTimestamp ), revEndTimestampType ); context.bind( getRevEndTimestampValue( configuration, revisionTimestamp ), revEndTimestampAttributeMapping );
} }
// Apply "WHERE (entity_id) = ?" // Apply "WHERE (entity_id) = ?"
context.addPrimaryKeyColumns( rootEntity.getIdentifierColumnNames() ); context.addPrimaryKeyColumns( rootEntity.getIdentifierColumnNames() );
context.bind( id, rootEntity.getIdentifierType() ); context.bind( id, rootEntity.getIdentifierMapping() );
// Apply "AND REV <> ?" // Apply "AND REV <> ?"
// todo (PropertyMapping) : need to be able to handle paths
final String path = configuration.getRevisionNumberPath(); final String path = configuration.getRevisionNumberPath();
context.addWhereColumn( rootAuditEntity.toColumns( path )[ 0 ], " <> ?" ); context.addWhereColumn( rootAuditEntity.toColumns( path )[ 0 ], " <> ?" );
context.bind( revisionNumber, rootAuditEntity.getPropertyType( path ) ); context.bind( revisionNumber, rootAuditEntity.getPropertyType( path ) );
// Apply "AND REVEND is null" // Apply "AND REVEND is null"
context.addWhereColumn( auditEntity.toColumns( revEndColumnName )[ 0 ], " is null" ); context.addWhereColumn( revEndColumnName, " is null" );
return context; return context;
} }
@ -607,8 +613,6 @@ private UpdateContext getNonRootUpdateContext(
final Queryable entity = getQueryable( entityName, session ); final Queryable entity = getQueryable( entityName, session );
final Queryable auditEntity = getQueryable( auditEntityName, session ); final Queryable auditEntity = getQueryable( auditEntityName, session );
final String revEndTimestampColumnName = configuration.getRevisionEndTimestampFieldName();
final Type revEndTimestampType = auditEntity.getPropertyType( revEndTimestampColumnName );
// The expected SQL is an update statement as follows: // The expected SQL is an update statement as follows:
// UPDATE audited_entity SET REVEND_TSTMP = ? WHERE (entity_id) = ? AND REV <> ? AND REVEND_TSMTP is null // UPDATE audited_entity SET REVEND_TSTMP = ? WHERE (entity_id) = ? AND REV <> ? AND REVEND_TSMTP is null
@ -617,8 +621,11 @@ private UpdateContext getNonRootUpdateContext(
// Apply "SET REVEND_TSTMP = ?" portion of the SQL // Apply "SET REVEND_TSTMP = ?" portion of the SQL
final Object revisionTimestamp = revisionTimestampGetter.get( revision ); final Object revisionTimestamp = revisionTimestampGetter.get( revision );
context.addColumn( auditEntity.toColumns( revEndTimestampColumnName )[ 0 ] ); final String revEndTimestampAttributeName = configuration.getRevisionEndTimestampFieldName();
context.bind( getRevEndTimestampValue( configuration, revisionTimestamp ), revEndTimestampType ); final AttributeMapping revEndTimestampAttributeMapping = auditEntity.findAttributeMapping( revEndTimestampAttributeName );
final String revEndTimestampColumnName = revEndTimestampAttributeMapping.getSelectable( 0 ).getSelectionExpression();
context.addColumn( revEndTimestampColumnName );
context.bind( getRevEndTimestampValue( configuration, revisionTimestamp ), revEndTimestampAttributeMapping );
// Apply "WHERE (entity_id) = ? AND REV <> ?" portion of the SQL // Apply "WHERE (entity_id) = ? AND REV <> ?" portion of the SQL
final Number revisionNumber = getRevisionNumber( configuration, revision ); final Number revisionNumber = getRevisionNumber( configuration, revision );
@ -628,11 +635,12 @@ private UpdateContext getNonRootUpdateContext(
context.bind( id, entity.getIdentifierType() ); context.bind( id, entity.getIdentifierType() );
// Apply "AND REV <> ?" // Apply "AND REV <> ?"
// todo (PropertyMapping) : need to be able to handle paths
context.addWhereColumn( configuration.getRevisionFieldName(), " <> ?" ); context.addWhereColumn( configuration.getRevisionFieldName(), " <> ?" );
context.bind( revisionNumber, auditEntity.getPropertyType( configuration.getRevisionNumberPath() ) ); context.bind( revisionNumber, auditEntity.getPropertyType( configuration.getRevisionNumberPath() ) );
// Apply "AND REVEND_TSTMP is null" // Apply "AND REVEND_TSTMP is null"
context.addWhereColumn( auditEntity.toColumns( revEndTimestampColumnName )[ 0 ], " is null" ); context.addWhereColumn( revEndTimestampColumnName, " is null" );
return context; return context;
} }
@ -669,15 +677,23 @@ public List<QueryParameterBinding> getBindings() {
} }
public void bind(Object value, Type type) { public void bind(Object value, Type type) {
bindings.add( new QueryParameterBinding( value, type ) ); bindings.add( new QueryParameterBindingType( value, type ) );
}
public void bind(Object value, ModelPart part) {
bindings.add( new QueryParameterBindingPart( value, part ) );
} }
} }
private static class QueryParameterBinding { private interface QueryParameterBinding {
int bind(int index, PreparedStatement statement, SessionImplementor session) throws SQLException;
}
private static class QueryParameterBindingType implements QueryParameterBinding {
private final Type type; private final Type type;
private final Object value; private final Object value;
public QueryParameterBinding(Object value, Type type) { public QueryParameterBindingType(Object value, Type type) {
this.type = type; this.type = type;
this.value = value; this.value = value;
} }
@ -687,4 +703,49 @@ public int bind(int index, PreparedStatement statement, SessionImplementor sessi
return type.getColumnSpan( session.getSessionFactory() ); return type.getColumnSpan( session.getSessionFactory() );
} }
} }
private static class QueryParameterBindingPart implements QueryParameterBinding {
private final ModelPart modelPart;
private final Object value;
public QueryParameterBindingPart(Object value, ModelPart modelPart) {
this.value = value;
this.modelPart = modelPart;
}
@Override
public int bind(
int index,
PreparedStatement statement,
SessionImplementor session) {
final MutableInteger position = new MutableInteger( index );
modelPart.breakDownJdbcValues(
value,
(jdbcValue, jdbcValueMapping) -> {
try {
//noinspection unchecked
jdbcValueMapping.getJdbcMapping().getJdbcValueBinder().bind(
statement,
jdbcValue,
position.getAndIncrease(),
session
);
}
catch (SQLException e) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(
e,
String.format(
Locale.ROOT,
"Error binding JDBC value relative to `%s`",
modelPart.getNavigableRole().getFullPath()
)
);
}
},
session
);
return modelPart.getJdbcTypeCount();
}
}
} }