Get rid of most capturing lambdas in write path

This commit is contained in:
Christian Beikov 2023-02-10 18:12:14 +01:00
parent 57f5769ee5
commit 9ef49c596d
51 changed files with 779 additions and 334 deletions

View File

@ -71,7 +71,7 @@ public class CompoundNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
naturalIdMapping().breakDownJdbcValues( naturalIdMapping().breakDownJdbcValues(
bindValue, bindValue,
(jdbcValue, jdbcValueMapping) -> { (valueIndex, jdbcValue, jdbcValueMapping) -> {
final Expression columnReference = resolveColumnReference( final Expression columnReference = resolveColumnReference(
rootTableGroup, rootTableGroup,
jdbcValueMapping, jdbcValueMapping,

View File

@ -63,7 +63,7 @@ public class SimpleNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
else { else {
naturalIdMapping().getAttribute().breakDownJdbcValues( naturalIdMapping().getAttribute().breakDownJdbcValues(
bindValue, bindValue,
(jdbcValue, jdbcValueMapping) -> { (valueIndex, jdbcValue, jdbcValueMapping) -> {
final Expression columnReference = resolveColumnReference( final Expression columnReference = resolveColumnReference(
rootTableGroup, rootTableGroup,
jdbcValueMapping, jdbcValueMapping,

View File

@ -218,14 +218,14 @@ public interface Bindable extends JdbcMappingContainer {
@FunctionalInterface @FunctionalInterface
interface JdbcValuesConsumer extends JdbcValuesBiConsumer<Object, Object> { interface JdbcValuesConsumer extends JdbcValuesBiConsumer<Object, Object> {
@Override @Override
default void consume(int selectionIndex, Object o, Object o2, Object jdbcValue, JdbcMapping jdbcMapping) { default void consume(int valueIndex, Object o, Object o2, Object jdbcValue, JdbcMapping jdbcMapping) {
consume( selectionIndex, jdbcValue, jdbcMapping ); consume( valueIndex, jdbcValue, jdbcMapping );
} }
/** /**
* Consume a JDBC-level jdbcValue. The JDBC jdbcMapping descriptor is also passed in * Consume a JDBC-level jdbcValue. The JDBC jdbcMapping descriptor is also passed in
*/ */
void consume(int selectionIndex, Object jdbcValue, JdbcMapping jdbcMapping); void consume(int valueIndex, Object jdbcValue, JdbcMapping jdbcMapping);
} }
/** /**
@ -236,6 +236,6 @@ public interface Bindable extends JdbcMappingContainer {
/** /**
* Consume a JDBC-level jdbcValue. The JDBC jdbcMapping descriptor is also passed in * Consume a JDBC-level jdbcValue. The JDBC jdbcMapping descriptor is also passed in
*/ */
void consume(int selectionIndex, X x, Y y, Object jdbcValue, JdbcMapping jdbcMapping); void consume(int valueIndex, X x, Y y, Object jdbcValue, JdbcMapping jdbcMapping);
} }
} }

View File

@ -123,10 +123,17 @@ public interface ModelPart extends MappingModelExpressible {
DomainResultCreationState creationState, DomainResultCreationState creationState,
BiConsumer<SqlSelection,JdbcMapping> selectionConsumer); BiConsumer<SqlSelection,JdbcMapping> selectionConsumer);
/**
* A short hand form of {@link #forEachSelectable(int, SelectableConsumer)}, that passes 0 as offset.
*/
default int forEachSelectable(SelectableConsumer consumer) { default int forEachSelectable(SelectableConsumer consumer) {
return forEachSelectable( 0, consumer ); return forEachSelectable( 0, consumer );
} }
/**
* Visits each selectable mapping with the selectable index offset by the given value.
* Returns the amount of jdbc types that have been visited.
*/
default int forEachSelectable(int offset, SelectableConsumer consumer) { default int forEachSelectable(int offset, SelectableConsumer consumer) {
return 0; return 0;
} }
@ -135,21 +142,56 @@ public interface ModelPart extends MappingModelExpressible {
return null; return null;
} }
@FunctionalInterface /**
interface JdbcValueConsumer { * A short hand form of {@link #breakDownJdbcValues(Object, int, Object, Object, JdbcValueBiConsumer, SharedSessionContractImplementor)},
void consume(Object value, SelectableMapping jdbcValueMapping); * that passes 0 as offset and null for the two values {@code X} and {@code Y}.
*/
default int breakDownJdbcValues(
Object domainValue,
JdbcValueConsumer valueConsumer,
SharedSessionContractImplementor session) {
return breakDownJdbcValues( domainValue, 0, null, null, valueConsumer, session );
} }
void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session); /**
* Breaks down the domain value to its constituent JDBC values.
*
* Think of it as breaking the multi-dimensional array into a visitable flat array.
* Additionally, it passes through the values {@code X} and {@code Y} to the consumer.
* Returns the amount of jdbc types that have been visited.
*/
<X, Y> int breakDownJdbcValues(
Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session);
@FunctionalInterface /**
interface IndexedJdbcValueConsumer { * A short hand form of {@link #decompose(Object, int, Object, Object, JdbcValueBiConsumer, SharedSessionContractImplementor)},
void consume(int valueIndex, Object value, SelectableMapping jdbcValueMapping); * that passes 0 as offset and null for the two values {@code X} and {@code Y}.
*/
default int decompose(
Object domainValue,
JdbcValueConsumer valueConsumer,
SharedSessionContractImplementor session) {
return decompose( domainValue, 0, null, null, valueConsumer, session );
} }
default void decompose(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { /**
breakDownJdbcValues( domainValue, valueConsumer, session ); * Similar to {@link #breakDownJdbcValues(Object, int, Object, Object, JdbcValueBiConsumer, SharedSessionContractImplementor)},
* but this method is supposed to be used for decomposing values for assignment expressions.
* Returns the amount of jdbc types that have been visited.
*/
default <X, Y> int decompose(
Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
} }
EntityMappingType findContainingEntityMapping(); EntityMappingType findContainingEntityMapping();
@ -158,4 +200,31 @@ public interface ModelPart extends MappingModelExpressible {
// NOTE : deepEquals to account for arrays (compound natural-id) // NOTE : deepEquals to account for arrays (compound natural-id)
return Objects.deepEquals( one, other ); return Objects.deepEquals( one, other );
} }
/**
* Functional interface for consuming the JDBC values.
*/
@FunctionalInterface
interface JdbcValueConsumer extends JdbcValueBiConsumer<Object, Object> {
@Override
default void consume(int valueIndex, Object x, Object y, Object value, SelectableMapping jdbcValueMapping) {
consume( valueIndex, value, jdbcValueMapping );
}
/**
* Consume a JDBC-level jdbcValue. The JDBC jdbcMapping descriptor is also passed in
*/
void consume(int valueIndex, Object value, SelectableMapping jdbcValueMapping);
}
/**
* Functional interface for consuming the JDBC values, along with two values of type {@code X} and {@code Y}.
*/
@FunctionalInterface
interface JdbcValueBiConsumer<X, Y> {
/**
* Consume a JDBC-level jdbcValue. The JDBC jdbcMapping descriptor is also passed in
*/
void consume(int valueIndex, X x, Y y, Object value, SelectableMapping jdbcValueMapping);
}
} }

View File

@ -239,8 +239,15 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( disassemble( domainValue, session ), this ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, disassemble( domainValue, session ), this );
return getJdbcTypeCount();
} }
@Override @Override

View File

@ -225,8 +225,15 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions,
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( domainValue, this ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, domainValue, this );
return getJdbcTypeCount();
} }
@Override @Override

View File

@ -259,8 +259,15 @@ public class AnyKeyPart implements BasicValuedModelPart, FetchOptions {
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( domainValue, this ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, domainValue, this );
return getJdbcTypeCount();
} }
@Override @Override

View File

@ -423,7 +423,14 @@ public class BasicAttributeMapping
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( disassemble( domainValue, session ), this ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, disassemble( domainValue, session ), this );
return getJdbcTypeCount();
} }
} }

View File

@ -186,8 +186,15 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( domainValue, this ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, domainValue, this );
return getJdbcTypeCount();
} }
@Override @Override

View File

@ -324,13 +324,26 @@ public class BasicValuedCollectionPart
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( disassemble( domainValue, session ), this ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, disassemble( domainValue, session ), this );
return getJdbcTypeCount();
} }
@Override @Override
public void decompose(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int decompose(
valueConsumer.consume( disassemble( domainValue, session ), this ); Object domainValue, int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, disassemble( domainValue, session ), this );
return getJdbcTypeCount();
} }
@Override @Override

View File

@ -198,12 +198,19 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD
@Override @Override
public int forEachSelectable(int offset, SelectableConsumer consumer) { public int forEachSelectable(int offset, SelectableConsumer consumer) {
consumer.accept( offset, this ); consumer.accept( offset, this );
return 1; return getJdbcTypeCount();
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( domainValue, this ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, domainValue, this );
return getJdbcTypeCount();
} }
@Override @Override

View File

@ -313,12 +313,19 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
int span = 0;
if ( domainValue == null ) { if ( domainValue == null ) {
attributes.forEach( for ( int i = 0; i < attributes.size(); i++ ) {
attributeMapping -> attributeMapping.breakDownJdbcValues( null, valueConsumer, session ) span += attributes.get( i ).breakDownJdbcValues( null, offset + span, x, y, valueConsumer, session );
); }
return; return span;
} }
assert domainValue instanceof Object[]; assert domainValue instanceof Object[];
@ -327,8 +334,9 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
assert values.length == attributes.size(); assert values.length == attributes.size();
for ( int i = 0; i < attributes.size(); i++ ) { for ( int i = 0; i < attributes.size(); i++ ) {
attributes.get( i ).breakDownJdbcValues( values[ i ], valueConsumer, session ); span += attributes.get( i ).breakDownJdbcValues( values[ i ], offset + span, x, y, valueConsumer, session );
} }
return span;
} }
@Override @Override

View File

@ -323,13 +323,25 @@ public class DiscriminatedAssociationAttributeMapping
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
discriminatorMapping.breakDownJdbcValues( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return discriminatorMapping.breakDownJdbcValues( offset, x, y, domainValue, valueConsumer, session );
} }
@Override @Override
public void decompose(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int decompose(
discriminatorMapping.decompose( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return discriminatorMapping.decompose( offset, x, y, domainValue, valueConsumer, session );
} }
@Override @Override

View File

@ -206,43 +206,55 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
return null; return null;
} }
public void breakDownJdbcValues(Object domainValue, ModelPart.JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
if ( domainValue == null ) { int offset,
valueConsumer.consume( null, getDiscriminatorPart() ); X x,
valueConsumer.consume( null, getKeyPart() ); Y y,
return;
}
final EntityMappingType concreteMappingType = determineConcreteType( domainValue, session );
final Object discriminator = getModelPart().resolveDiscriminatorForEntityType( concreteMappingType );
final Object disassembledDiscriminator = getDiscriminatorPart().disassemble( discriminator, session );
valueConsumer.consume( disassembledDiscriminator, getDiscriminatorPart() );
final EntityIdentifierMapping identifierMapping = concreteMappingType.getIdentifierMapping();
final Object identifier = identifierMapping.getIdentifier( domainValue );
final Object disassembledKey = getKeyPart().disassemble( identifier, session );
valueConsumer.consume( disassembledKey, getKeyPart() );
}
public void decompose(
Object domainValue, Object domainValue,
ModelPart.JdbcValueConsumer valueConsumer, ModelPart.JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
if ( domainValue == null ) { if ( domainValue == null ) {
valueConsumer.consume( null, getDiscriminatorPart() ); valueConsumer.consume( offset, x, y, null, getDiscriminatorPart() );
valueConsumer.consume( null, getKeyPart() ); valueConsumer.consume( offset + 1, x, y, null, getKeyPart() );
return; return getDiscriminatorPart().getJdbcTypeCount() + getKeyPart().getJdbcTypeCount();
} }
else {
final EntityMappingType concreteMappingType = determineConcreteType( domainValue, session );
final EntityMappingType concreteMappingType = determineConcreteType( domainValue, session ); final Object discriminator = getModelPart().resolveDiscriminatorForEntityType( concreteMappingType );
final Object disassembledDiscriminator = getDiscriminatorPart().disassemble( discriminator, session );
valueConsumer.consume( offset, x, y, disassembledDiscriminator, getDiscriminatorPart() );
final Object discriminator = getModelPart().resolveDiscriminatorForEntityType( concreteMappingType ); final EntityIdentifierMapping identifierMapping = concreteMappingType.getIdentifierMapping();
getDiscriminatorPart().decompose( discriminator, valueConsumer, session ); final Object identifier = identifierMapping.getIdentifier( domainValue );
final Object disassembledKey = getKeyPart().disassemble( identifier, session );
valueConsumer.consume( offset + 1, x, y, disassembledKey, getKeyPart() );
}
return getDiscriminatorPart().getJdbcTypeCount() + getKeyPart().getJdbcTypeCount();
}
final EntityIdentifierMapping identifierMapping = concreteMappingType.getIdentifierMapping(); public <X, Y> int decompose(
final Object identifier = identifierMapping.getIdentifier( domainValue ); int offset,
getKeyPart().decompose( identifier, valueConsumer, session ); X x,
Y y,
Object domainValue,
ModelPart.JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
if ( domainValue == null ) {
valueConsumer.consume( offset, x, y, null, getDiscriminatorPart() );
valueConsumer.consume( offset + 1, x, y, null, getKeyPart() );
}
else {
final EntityMappingType concreteMappingType = determineConcreteType( domainValue, session );
final Object discriminator = getModelPart().resolveDiscriminatorForEntityType( concreteMappingType );
getDiscriminatorPart().decompose( discriminator, offset, x, y, valueConsumer, session );
final EntityIdentifierMapping identifierMapping = concreteMappingType.getIdentifierMapping();
final Object identifier = identifierMapping.getIdentifier( domainValue );
getKeyPart().decompose( identifier, offset + 1, x, y, valueConsumer, session );
}
return getDiscriminatorPart().getJdbcTypeCount() + getKeyPart().getJdbcTypeCount();
} }
private EntityMappingType determineConcreteType(Object entity, SharedSessionContractImplementor session) { private EntityMappingType determineConcreteType(Object entity, SharedSessionContractImplementor session) {

View File

@ -285,13 +285,25 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
discriminatorMapping.breakDownJdbcValues( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return discriminatorMapping.breakDownJdbcValues( offset, x, y, domainValue, valueConsumer, session );
} }
@Override @Override
public void decompose(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int decompose(
discriminatorMapping.decompose( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return discriminatorMapping.decompose( offset, x, y, domainValue, valueConsumer, session );
} }
@Override @Override

View File

@ -695,8 +695,15 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
final int size = attributeMappings.size(); final int size = attributeMappings.size();
int span = 0;
if ( domainValue instanceof Object[] ) { if ( domainValue instanceof Object[] ) {
final Object[] values = (Object[]) domainValue; final Object[] values = (Object[]) domainValue;
assert values.length == size; assert values.length == size;
@ -704,7 +711,14 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
for ( int i = 0; i < size; i++ ) { for ( int i = 0; i < size; i++ ) {
final AttributeMapping attributeMapping = attributeMappings.get( i ); final AttributeMapping attributeMapping = attributeMappings.get( i );
final Object attributeValue = values[ i ]; final Object attributeValue = values[ i ];
attributeMapping.breakDownJdbcValues( attributeValue, valueConsumer, session ); span += attributeMapping.breakDownJdbcValues(
attributeValue,
offset + span,
x,
y,
valueConsumer,
session
);
} }
} }
else { else {
@ -713,38 +727,54 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
final Object attributeValue = domainValue == null final Object attributeValue = domainValue == null
? null ? null
: attributeMapping.getPropertyAccess().getGetter().get( domainValue ); : attributeMapping.getPropertyAccess().getGetter().get( domainValue );
attributeMapping.breakDownJdbcValues( attributeValue, valueConsumer, session ); span += attributeMapping.breakDownJdbcValues(
attributeValue,
offset + span,
x,
y,
valueConsumer,
session
);
} }
} }
return span;
} }
@Override @Override
public void decompose(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int decompose(
Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
if ( shouldBindAggregateMapping() ) { if ( shouldBindAggregateMapping() ) {
valueConsumer.consume( domainValue, aggregateMapping ); valueConsumer.consume( offset, x, y, domainValue, aggregateMapping );
return 1;
} }
else if ( domainValue instanceof Object[] ) { int span = 0;
if ( domainValue instanceof Object[] ) {
final Object[] values = (Object[]) domainValue; final Object[] values = (Object[]) domainValue;
assert values.length == attributeMappings.size(); assert values.length == attributeMappings.size();
for ( int i = 0; i < attributeMappings.size(); i++ ) { for ( int i = 0; i < attributeMappings.size(); i++ ) {
final AttributeMapping attributeMapping = attributeMappings.get( i ); final AttributeMapping attributeMapping = attributeMappings.get( i );
final Object attributeValue = values[ i ]; final Object attributeValue = values[ i ];
attributeMapping.decompose( attributeValue, valueConsumer, session ); span += attributeMapping.decompose( attributeValue, offset + span, x, y, valueConsumer, session );
} }
} }
else { else {
attributeMappings.forEach( (attributeMapping) -> { for ( int i = 0; i < attributeMappings.size(); i++ ) {
if ( attributeMapping instanceof PluralAttributeMapping ) { final AttributeMapping attributeMapping = attributeMappings.get( i );
return; if ( !(attributeMapping instanceof PluralAttributeMapping )) {
final Object attributeValue = domainValue == null
? null
: attributeMapping.getPropertyAccess().getGetter().get( domainValue );
span += attributeMapping.decompose( attributeValue, offset + span, x, y, valueConsumer, session );
} }
}
final Object attributeValue = domainValue == null
? null
: attributeMapping.getPropertyAccess().getGetter().get( domainValue );
attributeMapping.decompose( attributeValue, valueConsumer, session );
} );
} }
return span;
} }
@Override @Override

View File

@ -208,13 +208,25 @@ public class EmbeddedAttributeMapping
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
} }
@Override @Override
public void decompose(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int decompose(
getEmbeddableTypeDescriptor().decompose( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return getEmbeddableTypeDescriptor().decompose( domainValue, offset, x, y, valueConsumer, session );
} }
@Override @Override

View File

@ -341,8 +341,14 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
} }
@Override @Override

View File

@ -532,23 +532,39 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
if ( domainValue == null ) { if ( domainValue == null ) {
keySelectableMappings.forEachSelectable( (index, selectable) -> { final int jdbcTypeCount = keySelectableMappings.getJdbcTypeCount();
valueConsumer.consume( null, selectable ); for ( int i = 0; i < jdbcTypeCount; i++ ) {
} ); valueConsumer.consume( offset + i, x, y, null, keySelectableMappings.getSelectable( i ) );
}
return jdbcTypeCount;
} }
else if ( domainValue instanceof Object[] ) { else if ( domainValue instanceof Object[] ) {
final Object[] values = (Object[]) domainValue; final Object[] values = (Object[]) domainValue;
keySelectableMappings.forEachSelectable( (index, selectable) -> { final int jdbcTypeCount = keySelectableMappings.getJdbcTypeCount();
valueConsumer.consume( values[ index ], selectable ); for ( int i = 0; i < jdbcTypeCount; i++ ) {
} ); valueConsumer.consume( offset + i, x, y, values[i], keySelectableMappings.getSelectable( i ) );
}
return jdbcTypeCount;
} }
else { else {
final MutableInteger columnPosition = new MutableInteger(); final MutableInteger columnPosition = new MutableInteger();
keySide.getModelPart().breakDownJdbcValues( return keySide.getModelPart().breakDownJdbcValues(
domainValue, domainValue,
(jdbcValue, jdbcValueMapping) -> valueConsumer.consume( offset,
x,
y,
(valueIndex, arg1, arg2, jdbcValue, jdbcValueMapping) -> valueConsumer.consume(
offset,
arg1,
arg2,
jdbcValue, jdbcValue,
keySelectableMappings.getSelectable( columnPosition.getAndIncrement() ) keySelectableMappings.getSelectable( columnPosition.getAndIncrement() )
), ),

View File

@ -131,8 +131,14 @@ public class EmbeddedIdentifierMappingImpl
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
} }
@Override @Override

View File

@ -154,8 +154,15 @@ public class EntityRowIdMappingImpl implements EntityRowIdMapping {
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( domainValue, this ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, domainValue, this );
return getJdbcTypeCount();
} }
@Override @Override

View File

@ -290,8 +290,15 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( domainValue, this ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, domainValue, this );
return getJdbcTypeCount();
} }
private SqlSelection resolveSqlSelection(TableGroup tableGroup, DomainResultCreationState creationState) { private SqlSelection resolveSqlSelection(TableGroup tableGroup, DomainResultCreationState creationState) {

View File

@ -367,11 +367,20 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
attributeMappings.forEach( (attribute) -> { Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
int span = 0;
for ( int i = 0; i < attributeMappings.size(); i++ ) {
final AttributeMapping attribute = attributeMappings.get( i );
final Object attributeValue = attribute.getValue( domainValue ); final Object attributeValue = attribute.getValue( domainValue );
attribute.breakDownJdbcValues( attributeValue, valueConsumer, session ); span += attribute.breakDownJdbcValues( attributeValue, offset + span, x, y, valueConsumer, session );
} ); }
return span;
} }
@Override @Override

View File

@ -262,8 +262,13 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
identifierValueMapper.breakDownJdbcValues( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer, SharedSessionContractImplementor session) {
return identifierValueMapper.breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
} }
@Override @Override

View File

@ -137,8 +137,13 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
fkTargetModelPart.breakDownJdbcValues( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer, SharedSessionContractImplementor session) {
return fkTargetModelPart.breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
} }
@Override @Override
@ -158,9 +163,18 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple
} }
@Override @Override
public void decompose(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int decompose(
foreignKey.getKeyPart().decompose( Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return foreignKey.getKeyPart().decompose(
foreignKey.getAssociationKeyFromSide( domainValue, foreignKey.getTargetSide(), session ), foreignKey.getAssociationKeyFromSide( domainValue, foreignKey.getTargetSide(), session ),
offset,
x,
y,
valueConsumer, valueConsumer,
session session
); );

View File

@ -284,8 +284,13 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
identifierValueMapper.breakDownJdbcValues( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer, SharedSessionContractImplementor session) {
return identifierValueMapper.breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
} }
@Override @Override

View File

@ -82,12 +82,18 @@ public class OneToManyCollectionPart extends AbstractEntityCollectionPart implem
} }
@Override @Override
public void breakDownJdbcValues( public <X, Y> int breakDownJdbcValues(
Object domainValue, Object domainValue,
JdbcValueConsumer valueConsumer, int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
getAssociatedEntityMappingType().getIdentifierMapping().breakDownJdbcValues( return getAssociatedEntityMappingType().getIdentifierMapping().breakDownJdbcValues(
disassemble( domainValue, session ), disassemble( domainValue, session ),
offset,
x,
y,
valueConsumer, valueConsumer,
session session
); );

View File

@ -912,7 +912,13 @@ public class PluralAttributeMappingImpl
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@ -462,12 +462,19 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
JdbcValuesBiConsumer<X, Y> valuesConsumer, JdbcValuesBiConsumer<X, Y> valuesConsumer,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
valuesConsumer.consume( offset, x, y, value, getJdbcMapping() ); valuesConsumer.consume( offset, x, y, value, getJdbcMapping() );
return 1; return getJdbcTypeCount();
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( disassemble( domainValue, session ), keySide.getModelPart() ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, disassemble( domainValue, session ), keySide.getModelPart() );
return getJdbcTypeCount();
} }
@Override @Override

View File

@ -243,8 +243,14 @@ public class SimpleNaturalIdMapping extends AbstractNaturalIdMapping implements
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
attribute.breakDownJdbcValues( domainValue, valueConsumer, session ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
return attribute.breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
} }
@Override @Override

View File

@ -2022,16 +2022,19 @@ public class ToOneAttributeMapping
} }
@Override @Override
public void breakDownJdbcValues( public <X, Y> int breakDownJdbcValues(
Object domainValue, Object domainValue,
JdbcValueConsumer valueConsumer, int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
if ( cardinality == Cardinality.ONE_TO_ONE && sideNature == ForeignKeyDescriptor.Nature.TARGET ) { if ( cardinality == Cardinality.ONE_TO_ONE && sideNature == ForeignKeyDescriptor.Nature.TARGET ) {
return; return 0;
} }
final Object value = extractValue( domainValue, session ); final Object value = extractValue( domainValue, session );
foreignKeyDescriptor.breakDownJdbcValues( value, valueConsumer, session ); return foreignKeyDescriptor.breakDownJdbcValues( value, offset, x, y, valueConsumer, session );
} }
private Object extractValue(Object domainValue, SharedSessionContractImplementor session) { private Object extractValue(Object domainValue, SharedSessionContractImplementor session) {

View File

@ -319,29 +319,47 @@ public class VirtualIdEmbeddable extends AbstractEmbeddableMapping implements Id
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
attributeMappings.forEach( (attribute) -> { Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer, SharedSessionContractImplementor session) {
int span = 0;
for ( int i = 0; i < attributeMappings.size(); i++ ) {
final AttributeMapping attribute = attributeMappings.get( i );
final Object attributeValue = attribute.getValue( domainValue ); final Object attributeValue = attribute.getValue( domainValue );
attribute.breakDownJdbcValues( attributeValue, valueConsumer, session ); span += attribute.breakDownJdbcValues( attributeValue, offset + span, x, y, valueConsumer, session );
} ); }
return span;
} }
@Override @Override
public void decompose(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int decompose(
Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer, SharedSessionContractImplementor session) {
if ( idMapping.getIdClassEmbeddable() != null ) { if ( idMapping.getIdClassEmbeddable() != null ) {
// during decompose, if there is an IdClass for the entity the // during decompose, if there is an IdClass for the entity the
// incoming `domainValue` should be an instance of that IdClass // incoming `domainValue` should be an instance of that IdClass
idMapping.getIdClassEmbeddable().decompose( domainValue, valueConsumer, session ); return idMapping.getIdClassEmbeddable().decompose( domainValue, offset, x, y, valueConsumer, session );
} }
else { else {
int span = 0;
for ( int i = 0; i < attributeMappings.size(); i++ ) { for ( int i = 0; i < attributeMappings.size(); i++ ) {
final AttributeMapping attributeMapping = attributeMappings.get( i ); final AttributeMapping attributeMapping = attributeMappings.get( i );
attributeMapping.decompose( span += attributeMapping.decompose(
attributeMapping.getValue( domainValue ), attributeMapping.getValue( domainValue ),
offset + span,
x,
y,
valueConsumer, valueConsumer,
session session
); );
} }
return span;
} }
} }

View File

@ -11,6 +11,7 @@ import org.hibernate.MappingException;
import org.hibernate.cache.CacheException; import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.access.CollectionDataAccess; import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
import org.hibernate.engine.jdbc.mutation.ParameterUsage; import org.hibernate.engine.jdbc.mutation.ParameterUsage;
import org.hibernate.engine.jdbc.mutation.internal.MutationQueryOptions; import org.hibernate.engine.jdbc.mutation.internal.MutationQueryOptions;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -22,7 +23,6 @@ import org.hibernate.mapping.Collection;
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor; import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
import org.hibernate.metamodel.mapping.CollectionPart; import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.collection.mutation.CollectionTableMapping; import org.hibernate.persister.collection.mutation.CollectionTableMapping;
@ -331,7 +331,7 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
Object rowValue, Object rowValue,
int rowPosition, int rowPosition,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
RowMutationOperations.ValuesBindingConsumer jdbcValueConsumer) { JdbcValueBindings jdbcValueBindings) {
final PluralAttributeMapping attributeMapping = getAttributeMapping(); final PluralAttributeMapping attributeMapping = getAttributeMapping();
if ( key == null ) { if ( key == null ) {
@ -339,14 +339,24 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
} }
final ForeignKeyDescriptor foreignKey = attributeMapping.getKeyDescriptor(); final ForeignKeyDescriptor foreignKey = attributeMapping.getKeyDescriptor();
foreignKey.getKeyPart().decompose( key, jdbcValueConsumer, session ); foreignKey.getKeyPart().decompose(
key,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_VALUE_SETTER,
session
);
final MutableInteger columnPositionCount = new MutableInteger(); final MutableInteger columnPositionCount = new MutableInteger();
if ( attributeMapping.getIdentifierDescriptor() != null ) { if ( attributeMapping.getIdentifierDescriptor() != null ) {
getAttributeMapping().getIdentifierDescriptor().decompose( getAttributeMapping().getIdentifierDescriptor().decompose(
collection.getIdentifier( rowValue, rowPosition ), collection.getIdentifier( rowValue, rowPosition ),
jdbcValueConsumer, 0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_VALUE_SETTER,
session session
); );
} }
@ -361,15 +371,17 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
getAttributeMapping().getIndexDescriptor().decompose( getAttributeMapping().getIndexDescriptor().decompose(
incrementIndexByBase( collection.getIndex( rowValue, rowPosition, this ) ), incrementIndexByBase( collection.getIndex( rowValue, rowPosition, this ) ),
(jdbcValue, jdbcValueMapping) -> { 0,
indexColumnIsSettable,
jdbcValueBindings,
(valueIndex, settable, bindings, jdbcValue, jdbcValueMapping) -> {
if ( !jdbcValueMapping.getContainingTableExpression().equals( getTableName() ) ) { if ( !jdbcValueMapping.getContainingTableExpression().equals( getTableName() ) ) {
// indicates a many-to-many mapping and the index is contained on the // indicates a many-to-many mapping and the index is contained on the
// associated entity table - we skip it here // associated entity table - we skip it here
return; return;
} }
final int columnPosition = columnPositionCount.getAndIncrement(); if ( settable[valueIndex] ) {
if ( indexColumnIsSettable[columnPosition] ) { bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.SET );
jdbcValueConsumer.consume( jdbcValue, jdbcValueMapping );
} }
}, },
session session
@ -380,10 +392,12 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
attributeMapping.getElementDescriptor().decompose( attributeMapping.getElementDescriptor().decompose(
collection.getElement( rowValue ), collection.getElement( rowValue ),
(jdbcValue, jdbcValueMapping) -> { 0,
final int columnPosition = columnPositionCount.getAndIncrement(); elementColumnIsSettable,
if ( elementColumnIsSettable[columnPosition] ) { jdbcValueBindings,
jdbcValueConsumer.consume( jdbcValue, jdbcValueMapping ); (valueIndex, settable, bindings, jdbcValue, jdbcValueMapping) -> {
if ( settable[valueIndex] ) {
bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.SET );
} }
}, },
session session
@ -477,16 +491,19 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
Object entry, Object entry,
int entryPosition, int entryPosition,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
RowMutationOperations.ValuesBindingConsumer jdbcValueConsumer) { JdbcValueBindings jdbcValueBindings) {
final Object element = collection.getElement( entry ); final Object element = collection.getElement( entry );
final CollectionPart elementDescriptor = getAttributeMapping().getElementDescriptor(); final CollectionPart elementDescriptor = getAttributeMapping().getElementDescriptor();
elementDescriptor.decompose( elementDescriptor.decompose(
element, element,
(jdbcValue, jdbcValueMapping) -> { 0,
jdbcValueBindings,
null,
(valueIndex, bindings, y, jdbcValue, jdbcValueMapping) -> {
if ( !jdbcValueMapping.isUpdateable() || jdbcValueMapping.isFormula() ) { if ( !jdbcValueMapping.isUpdateable() || jdbcValueMapping.isFormula() ) {
return; return;
} }
jdbcValueConsumer.consumeJdbcValueBinding( bindings.bindValue(
jdbcValue, jdbcValue,
jdbcValueMapping, jdbcValueMapping,
ParameterUsage.SET ParameterUsage.SET
@ -502,29 +519,53 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
Object entry, Object entry,
int entryPosition, int entryPosition,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
ModelPart.JdbcValueConsumer restrictor) { JdbcValueBindings jdbcValueBindings) {
if ( getAttributeMapping().getIdentifierDescriptor() != null ) { if ( getAttributeMapping().getIdentifierDescriptor() != null ) {
final CollectionIdentifierDescriptor identifierDescriptor = getAttributeMapping().getIdentifierDescriptor(); final CollectionIdentifierDescriptor identifierDescriptor = getAttributeMapping().getIdentifierDescriptor();
final Object identifier = collection.getIdentifier( entry, entryPosition ); final Object identifier = collection.getIdentifier( entry, entryPosition );
identifierDescriptor.decompose( identifier, restrictor, session ); identifierDescriptor.decompose(
identifier,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_RESTRICTOR,
session
);
} }
else { else {
getAttributeMapping().getKeyDescriptor().getKeyPart().decompose( key, restrictor, session ); getAttributeMapping().getKeyDescriptor().getKeyPart().decompose(
key,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_RESTRICTOR,
session
);
if ( getAttributeMapping().getIndexDescriptor() != null && !indexContainsFormula ) { if ( getAttributeMapping().getIndexDescriptor() != null && !indexContainsFormula ) {
final Object index = collection.getIndex( entry, entryPosition, getAttributeMapping().getCollectionDescriptor() ); final Object index = collection.getIndex( entry, entryPosition, getAttributeMapping().getCollectionDescriptor() );
final Object adjustedIndex = incrementIndexByBase( index ); final Object adjustedIndex = incrementIndexByBase( index );
getAttributeMapping().getIndexDescriptor().decompose( adjustedIndex, restrictor, session ); getAttributeMapping().getIndexDescriptor().decompose(
adjustedIndex,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_RESTRICTOR,
session
);
} }
else { else {
final Object snapshotElement = collection.getSnapshotElement( entry, entryPosition ); final Object snapshotElement = collection.getSnapshotElement( entry, entryPosition );
getAttributeMapping().getElementDescriptor().decompose( getAttributeMapping().getElementDescriptor().decompose(
snapshotElement, snapshotElement,
(jdbcValue, jdbcValueMapping) -> { 0,
jdbcValueBindings,
null,
(valueIndex, bindings, noop, jdbcValue, jdbcValueMapping) -> {
if ( jdbcValueMapping.isNullable() || jdbcValueMapping.isFormula() ) { if ( jdbcValueMapping.isNullable() || jdbcValueMapping.isFormula() ) {
return; return;
} }
restrictor.consume( jdbcValue, jdbcValueMapping ); bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.RESTRICT );
}, },
session session
); );
@ -616,30 +657,50 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
Object rowValue, Object rowValue,
int rowPosition, int rowPosition,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
ModelPart.JdbcValueConsumer restrictor) { JdbcValueBindings jdbcValueBindings) {
final PluralAttributeMapping attributeMapping = getAttributeMapping(); final PluralAttributeMapping attributeMapping = getAttributeMapping();
if ( attributeMapping.getIdentifierDescriptor() != null ) { if ( attributeMapping.getIdentifierDescriptor() != null ) {
attributeMapping.getIdentifierDescriptor().decompose( rowValue, restrictor, session ); attributeMapping.getIdentifierDescriptor().decompose(
rowValue,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_RESTRICTOR,
session
);
} }
else { else {
getAttributeMapping().getKeyDescriptor().getKeyPart().decompose( keyValue, restrictor, session ); getAttributeMapping().getKeyDescriptor().getKeyPart().decompose(
keyValue,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_RESTRICTOR,
session
);
if ( hasPhysicalIndexColumn() ) { if ( hasPhysicalIndexColumn() ) {
attributeMapping.getIndexDescriptor().decompose( attributeMapping.getIndexDescriptor().decompose(
incrementIndexByBase( rowValue ), incrementIndexByBase( rowValue ),
restrictor, 0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_RESTRICTOR,
session session
); );
} }
else { else {
attributeMapping.getElementDescriptor().decompose( attributeMapping.getElementDescriptor().decompose(
rowValue, rowValue,
(jdbcValue, jdbcValueMapping) -> { 0,
jdbcValueBindings,
null,
(valueIndex, bindings, noop, jdbcValue, jdbcValueMapping) -> {
if ( jdbcValueMapping.isNullable() || jdbcValueMapping.isFormula() ) { if ( jdbcValueMapping.isNullable() || jdbcValueMapping.isFormula() ) {
return; return;
} }
restrictor.consume( jdbcValue, jdbcValueMapping ); bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.RESTRICT );
}, },
session session
); );

View File

@ -31,7 +31,6 @@ import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.ModelPart.JdbcValueConsumer;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart; import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
@ -243,11 +242,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
entry, entry,
nextIndex, nextIndex,
session, session,
(jdbcValue, jdbcValueMapping, usage) -> jdbcValueBindings.bindValue( jdbcValueBindings
jdbcValue,
jdbcValueMapping,
usage
)
); );
updateRowRestrictions.applyRestrictions( updateRowRestrictions.applyRestrictions(
@ -256,11 +251,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
entry, entry,
nextIndex, nextIndex,
session, session,
(jdbcValue, jdbcValueMapping) -> jdbcValueBindings.bindValue( jdbcValueBindings
jdbcValue,
jdbcValueMapping,
ParameterUsage.RESTRICT
)
); );
mutationExecutor.execute( collection, null, null, null, session ); mutationExecutor.execute( collection, null, null, null, session );
@ -621,10 +612,24 @@ public class OneToManyPersister extends AbstractCollectionPersister {
Object rowValue, Object rowValue,
int rowPosition, int rowPosition,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
JdbcValueConsumer jdbcValueConsumer) { JdbcValueBindings jdbcValueBindings) {
final PluralAttributeMapping pluralAttribute = getAttributeMapping(); final PluralAttributeMapping pluralAttribute = getAttributeMapping();
pluralAttribute.getKeyDescriptor().decompose( keyValue, jdbcValueConsumer, session ); pluralAttribute.getKeyDescriptor().decompose(
pluralAttribute.getElementDescriptor().decompose( rowValue, jdbcValueConsumer, session ); keyValue,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_RESTRICTOR,
session
);
pluralAttribute.getElementDescriptor().decompose(
rowValue,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_RESTRICTOR,
session
);
} }
@ -658,21 +663,31 @@ public class OneToManyPersister extends AbstractCollectionPersister {
Object rowValue, Object rowValue,
int rowPosition, int rowPosition,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
RowMutationOperations.ValuesBindingConsumer bindingsConsumer) { JdbcValueBindings jdbcValueBindings) {
final PluralAttributeMapping attributeMapping = getAttributeMapping(); final PluralAttributeMapping attributeMapping = getAttributeMapping();
attributeMapping.getKeyDescriptor().getKeyPart().decompose( keyValue, bindingsConsumer, session ); attributeMapping.getKeyDescriptor().getKeyPart().decompose(
keyValue,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_VALUE_SETTER,
session
);
final CollectionPart indexDescriptor = attributeMapping.getIndexDescriptor(); final CollectionPart indexDescriptor = attributeMapping.getIndexDescriptor();
if ( indexDescriptor != null ) { if ( indexDescriptor != null ) {
indexDescriptor.decompose( indexDescriptor.decompose(
incrementIndexByBase( collection.getIndex( rowValue, rowPosition, this ) ), incrementIndexByBase( collection.getIndex( rowValue, rowPosition, this ) ),
(value, jdbcValueMapping) -> { 0,
jdbcValueBindings,
null,
(valueIndex, bindings, noop, value, jdbcValueMapping) -> {
if ( !jdbcValueMapping.isUpdateable() ) { if ( !jdbcValueMapping.isUpdateable() ) {
return; return;
} }
bindingsConsumer.consume( value, jdbcValueMapping ); bindings.bindValue( value, jdbcValueMapping, ParameterUsage.SET );
}, },
session session
); );
@ -683,11 +698,10 @@ public class OneToManyPersister extends AbstractCollectionPersister {
final EntityIdentifierMapping identifierMapping = elementDescriptor.getAssociatedEntityMappingType().getIdentifierMapping(); final EntityIdentifierMapping identifierMapping = elementDescriptor.getAssociatedEntityMappingType().getIdentifierMapping();
identifierMapping.decompose( identifierMapping.decompose(
identifierMapping.getIdentifier( elementValue ), identifierMapping.getIdentifier( elementValue ),
(jdbcValue, jdbcValueMapping) -> bindingsConsumer.consumeJdbcValueBinding( 0,
jdbcValue, jdbcValueBindings,
jdbcValueMapping, null,
ParameterUsage.RESTRICT RowMutationOperations.DEFAULT_RESTRICTOR,
),
session session
); );
} }
@ -754,16 +768,19 @@ public class OneToManyPersister extends AbstractCollectionPersister {
Object entry, Object entry,
int entryPosition, int entryPosition,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
RowMutationOperations.ValuesBindingConsumer bindingsConsumer) { JdbcValueBindings jdbcValueBindings) {
final Object index = collection.getIndex( entry, entryPosition, this ); final Object index = collection.getIndex( entry, entryPosition, this );
getAttributeMapping().getIndexDescriptor().decompose( getAttributeMapping().getIndexDescriptor().decompose(
index, index,
(jdbcValue, jdbcValueMapping) -> { 0,
jdbcValueBindings,
null,
(valueIndex, bindings, noop, jdbcValue, jdbcValueMapping) -> {
if ( !jdbcValueMapping.isUpdateable() ) { if ( !jdbcValueMapping.isUpdateable() ) {
return; return;
} }
bindingsConsumer.consume( jdbcValue, jdbcValueMapping ); bindings.bindValue( jdbcValue, jdbcValueMapping, ParameterUsage.SET );
}, },
session session
); );
@ -775,16 +792,30 @@ public class OneToManyPersister extends AbstractCollectionPersister {
Object entry, Object entry,
int entryPosition, int entryPosition,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
JdbcValueConsumer jdbcValueConsumer) { JdbcValueBindings jdbcValueBindings) {
final OneToManyCollectionPart elementDescriptor = (OneToManyCollectionPart) getAttributeMapping().getElementDescriptor(); final OneToManyCollectionPart elementDescriptor = (OneToManyCollectionPart) getAttributeMapping().getElementDescriptor();
final EntityMappingType associatedType = elementDescriptor.getAssociatedEntityMappingType(); final EntityMappingType associatedType = elementDescriptor.getAssociatedEntityMappingType();
final Object element = collection.getElement( entry ); final Object element = collection.getElement( entry );
final Object elementIdentifier = associatedType.getIdentifierMapping().getIdentifier( element ); final Object elementIdentifier = associatedType.getIdentifierMapping().getIdentifier( element );
associatedType.getIdentifierMapping().decompose( elementIdentifier, jdbcValueConsumer, session ); associatedType.getIdentifierMapping().decompose(
elementIdentifier,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_RESTRICTOR,
session
);
if ( getAttributeMapping().getIdentifierDescriptor() != null ) { if ( getAttributeMapping().getIdentifierDescriptor() != null ) {
final Object identifier = collection.getIdentifier( entry, entryPosition ); final Object identifier = collection.getIdentifier( entry, entryPosition );
getAttributeMapping().getIdentifierDescriptor().decompose( identifier, jdbcValueConsumer, session ); getAttributeMapping().getIdentifierDescriptor().decompose(
identifier,
0,
jdbcValueBindings,
null,
RowMutationOperations.DEFAULT_RESTRICTOR,
session
);
} }
} }

View File

@ -100,16 +100,7 @@ public class DeleteRowsCoordinatorStandard implements DeleteRowsCoordinator {
removal, removal,
deletionCount, deletionCount,
session, session,
(jdbcValue, jdbcValueMapping) -> { jdbcValueBindings
if ( jdbcValueMapping.isFormula() ) {
return;
}
jdbcValueBindings.bindValue(
jdbcValue,
jdbcValueMapping,
ParameterUsage.RESTRICT
);
}
); );
mutationExecutor.execute( removal, null, null, null, session ); mutationExecutor.execute( removal, null, null, null, session );

View File

@ -12,6 +12,7 @@ import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
import org.hibernate.engine.jdbc.mutation.MutationExecutor; import org.hibernate.engine.jdbc.mutation.MutationExecutor;
import org.hibernate.engine.jdbc.mutation.ParameterUsage;
import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
@ -112,7 +113,7 @@ public class InsertRowsCoordinatorStandard implements InsertRowsCoordinator {
entry, entry,
entryCount, entryCount,
session, session,
jdbcValueBindings::bindValue jdbcValueBindings
); );
mutationExecutor.execute( entry, null, null, null, session ); mutationExecutor.execute( entry, null, null, null, session );
} }

View File

@ -9,7 +9,6 @@ package org.hibernate.persister.collection.mutation;
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
import org.hibernate.engine.jdbc.mutation.MutationExecutor; import org.hibernate.engine.jdbc.mutation.MutationExecutor;
import org.hibernate.engine.jdbc.mutation.ParameterUsage;
import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
@ -100,13 +99,10 @@ public class RemoveCoordinatorStandard implements RemoveCoordinator {
final ForeignKeyDescriptor fkDescriptor = mutationTarget.getTargetPart().getKeyDescriptor(); final ForeignKeyDescriptor fkDescriptor = mutationTarget.getTargetPart().getKeyDescriptor();
fkDescriptor.getKeyPart().decompose( fkDescriptor.getKeyPart().decompose(
key, key,
(jdbcValue, jdbcValueMapping) -> { 0,
jdbcValueBindings.bindValue( jdbcValueBindings,
jdbcValue, null,
jdbcValueMapping, RowMutationOperations.DEFAULT_RESTRICTOR,
ParameterUsage.RESTRICT
);
},
session session
); );

View File

@ -7,11 +7,11 @@
package org.hibernate.persister.collection.mutation; package org.hibernate.persister.collection.mutation;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
import org.hibernate.engine.jdbc.mutation.ParameterUsage; import org.hibernate.engine.jdbc.mutation.ParameterUsage;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.NullnessHelper; import org.hibernate.internal.util.NullnessHelper;
import org.hibernate.metamodel.mapping.ModelPart.JdbcValueConsumer; import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationOperation;
import org.hibernate.sql.model.ast.MutatingTableReference; import org.hibernate.sql.model.ast.MutatingTableReference;
import org.hibernate.sql.model.jdbc.JdbcMutationOperation; import org.hibernate.sql.model.jdbc.JdbcMutationOperation;
@ -25,6 +25,12 @@ import org.hibernate.sql.model.jdbc.JdbcMutationOperation;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class RowMutationOperations { public class RowMutationOperations {
public static final ModelPart.JdbcValueBiConsumer<JdbcValueBindings, Object> DEFAULT_RESTRICTOR = (valueIndex, jdbcValueBindings, o, value, jdbcValueMapping) -> {
jdbcValueBindings.bindValue( value, jdbcValueMapping, ParameterUsage.RESTRICT );
};
public static final ModelPart.JdbcValueBiConsumer<JdbcValueBindings, Object> DEFAULT_VALUE_SETTER = (valueIndex, jdbcValueBindings, o, value, jdbcValueMapping) -> {
jdbcValueBindings.bindValue( value, jdbcValueMapping, ParameterUsage.SET );
};
private final CollectionMutationTarget target; private final CollectionMutationTarget target;
private final OperationProducer insertRowOperationProducer; private final OperationProducer insertRowOperationProducer;
@ -163,7 +169,7 @@ public class RowMutationOperations {
Object rowValue, Object rowValue,
int rowPosition, int rowPosition,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
JdbcValueConsumer restrictor); JdbcValueBindings jdbcValueBindings);
} }
@FunctionalInterface @FunctionalInterface
@ -174,23 +180,7 @@ public class RowMutationOperations {
Object rowValue, Object rowValue,
int rowPosition, int rowPosition,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
ValuesBindingConsumer valuesBindingConsumer); JdbcValueBindings jdbcValueBindings);
} }
/**
* Consumer for insert-value bindings
*
* Unfortunate we need `usage` here, but it is needed to account for
* update-as-insert handling of one-to-many handling
*/
@FunctionalInterface
public interface ValuesBindingConsumer extends JdbcValueConsumer {
void consumeJdbcValueBinding(Object value, SelectableMapping jdbcValueMapping, ParameterUsage usage);
@Override
default void consume(Object value, SelectableMapping jdbcValueMapping) {
// insert values will be SET most of the time
consumeJdbcValueBinding( value, jdbcValueMapping, ParameterUsage.SET );
}
}
} }

View File

@ -88,11 +88,7 @@ public class UpdateRowsCoordinatorOneToMany extends AbstractUpdateRowsCoordinato
entry, entry,
entryPosition, entryPosition,
session, session,
(jdbcValue, jdbcValueMapping) -> jdbcValueBindings.bindValue( jdbcValueBindings
jdbcValue,
jdbcValueMapping,
ParameterUsage.RESTRICT
)
); );
mutationExecutor.execute( entry, null, null, null, session ); mutationExecutor.execute( entry, null, null, null, session );
@ -150,11 +146,7 @@ public class UpdateRowsCoordinatorOneToMany extends AbstractUpdateRowsCoordinato
entry, entry,
entryPosition, entryPosition,
session, session,
(jdbcValue, jdbcValueMapping, usage) -> jdbcValueBindings.bindValue( jdbcValueBindings
jdbcValue,
jdbcValueMapping,
usage
)
); );
mutationExecutor.execute( entry, null, null, null, session ); mutationExecutor.execute( entry, null, null, null, session );

View File

@ -126,11 +126,7 @@ public class UpdateRowsCoordinatorStandard extends AbstractUpdateRowsCoordinator
entry, entry,
entryPosition, entryPosition,
session, session,
(jdbcValue, jdbcValueMapping, usage) -> mutationExecutor.getJdbcValueBindings().bindValue( mutationExecutor.getJdbcValueBindings()
jdbcValue,
jdbcValueMapping,
usage
)
); );
rowMutationOperations.getUpdateRowRestrictions().applyRestrictions( rowMutationOperations.getUpdateRowRestrictions().applyRestrictions(
@ -139,11 +135,7 @@ public class UpdateRowsCoordinatorStandard extends AbstractUpdateRowsCoordinator
entry, entry,
entryPosition, entryPosition,
session, session,
(jdbcValue, jdbcValueMapping) -> mutationExecutor.getJdbcValueBindings().bindValue( mutationExecutor.getJdbcValueBindings()
jdbcValue,
jdbcValueMapping,
ParameterUsage.RESTRICT
)
); );
mutationExecutor.execute( collection, null, null, null, session ); mutationExecutor.execute( collection, null, null, null, session );

View File

@ -490,21 +490,36 @@ public interface EntityPersister extends EntityMappingType, RootTableGroupProduc
} }
@Override @Override
default void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { default <X, Y> int breakDownJdbcValues(
Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
int span = 0;
if ( domainValue instanceof Object[] ) { if ( domainValue instanceof Object[] ) {
final Object[] values = (Object[]) domainValue; final Object[] values = (Object[]) domainValue;
for ( int i = 0; i < getNumberOfAttributeMappings(); i++ ) { for ( int i = 0; i < getNumberOfAttributeMappings(); i++ ) {
final AttributeMapping attributeMapping = getAttributeMapping( i ); final AttributeMapping attributeMapping = getAttributeMapping( i );
attributeMapping.breakDownJdbcValues( values[ i ], valueConsumer, session ); span += attributeMapping.breakDownJdbcValues( values[ i ], offset + span, x, y, valueConsumer, session );
} }
} }
else { else {
for ( int i = 0; i < getNumberOfAttributeMappings(); i++ ) { for ( int i = 0; i < getNumberOfAttributeMappings(); i++ ) {
final AttributeMapping attributeMapping = getAttributeMapping( i ); final AttributeMapping attributeMapping = getAttributeMapping( i );
final Object attributeValue = attributeMapping.getPropertyAccess().getGetter().get( domainValue ); final Object attributeValue = attributeMapping.getPropertyAccess().getGetter().get( domainValue );
attributeMapping.breakDownJdbcValues( attributeValue, valueConsumer, session ); span += attributeMapping.breakDownJdbcValues(
attributeValue,
offset + span,
x,
y,
valueConsumer,
session
);
} }
} }
return span;
} }
/** /**

View File

@ -16,6 +16,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.persister.entity.AbstractEntityPersister; import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.persister.entity.AttributeMappingsList;
import org.hibernate.sql.model.ModelMutationLogging; import org.hibernate.sql.model.ModelMutationLogging;
import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationOperation;
import org.hibernate.sql.model.MutationOperationGroup; import org.hibernate.sql.model.MutationOperationGroup;
@ -112,26 +113,31 @@ public abstract class AbstractMutationCoordinator {
Object[] loadedState, Object[] loadedState,
SharedSessionContractImplementor session, SharedSessionContractImplementor session,
JdbcValueBindings jdbcValueBindings) { JdbcValueBindings jdbcValueBindings) {
if ( entityPersister().hasPartitionedSelectionMapping() ) { final AbstractEntityPersister persister = entityPersister();
entityPersister().forEachAttributeMapping( if ( persister.hasPartitionedSelectionMapping() ) {
(index, attributeMapping) -> { final AttributeMappingsList attributeMappings = persister.getAttributeMappings();
if ( attributeMapping.hasPartitionedSelectionMapping() ) { final int size = attributeMappings.size();
attributeMapping.decompose( for ( int i = 0; i < size; i++ ) {
loadedState[index], final AttributeMapping attributeMapping = attributeMappings.get( i );
(value, jdbcValueMapping) -> { if ( attributeMapping.hasPartitionedSelectionMapping() ) {
if ( jdbcValueMapping.isPartitioned() ) { attributeMapping.decompose(
jdbcValueBindings.bindValue( loadedState[i],
value, 0,
jdbcValueMapping, jdbcValueBindings,
ParameterUsage.RESTRICT null,
); (valueIndex, bindings, noop, value, jdbcValueMapping) -> {
} if ( jdbcValueMapping.isPartitioned() ) {
}, bindings.bindValue(
session value,
); jdbcValueMapping,
} ParameterUsage.RESTRICT
} );
); }
},
session
);
}
}
} }
} }
} }

View File

@ -170,14 +170,17 @@ public class DeleteCoordinator extends AbstractMutationCoordinator {
final String mutationTableName = persister.getAttributeMutationTableName( attributeIndex ); final String mutationTableName = persister.getAttributeMutationTableName( attributeIndex );
attribute.breakDownJdbcValues( attribute.breakDownJdbcValues(
loadedValue, loadedValue,
(jdbcValue, jdbcValueMapping) -> { 0,
jdbcValueBindings,
mutationTableName,
(valueIndex, bindings, tableName, jdbcValue, jdbcValueMapping) -> {
if ( jdbcValue == null ) { if ( jdbcValue == null ) {
// presumably the SQL was generated with `is null` // presumably the SQL was generated with `is null`
return; return;
} }
jdbcValueBindings.bindValue( bindings.bindValue(
jdbcValue, jdbcValue,
mutationTableName, tableName,
jdbcValueMapping.getSelectionExpression(), jdbcValueMapping.getSelectionExpression(),
ParameterUsage.RESTRICT ParameterUsage.RESTRICT
); );

View File

@ -243,9 +243,12 @@ public class InsertCoordinator extends AbstractMutationCoordinator {
if ( !(mapping instanceof PluralAttributeMapping) ) { if ( !(mapping instanceof PluralAttributeMapping) ) {
mapping.decompose( mapping.decompose(
value, value,
(jdbcValue, selectableMapping) -> { 0,
jdbcValueBindings,
null,
(valueIndex, bindings, noop, jdbcValue, selectableMapping) -> {
if ( selectableMapping.isInsertable() ) { if ( selectableMapping.isInsertable() ) {
jdbcValueBindings.bindValue( bindings.bindValue(
jdbcValue, jdbcValue,
entityPersister().physicalTableNameForMutation( selectableMapping ), entityPersister().physicalTableNameForMutation( selectableMapping ),
selectableMapping.getSelectionExpression(), selectableMapping.getSelectionExpression(),

View File

@ -675,10 +675,13 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple
Object attributeLockValue) { Object attributeLockValue) {
attributeMapping.decompose( attributeMapping.decompose(
attributeLockValue, attributeLockValue,
(jdbcValue, columnMapping) -> { 0,
analysis,
null,
(valueIndex, updateAnalysis, noop, jdbcValue, columnMapping) -> {
if ( !columnMapping.isFormula() ) { if ( !columnMapping.isFormula() ) {
final EntityTableMapping tableMapping = entityPersister().getPhysicalTableMappingForMutation( columnMapping ); final EntityTableMapping tableMapping = entityPersister().getPhysicalTableMappingForMutation( columnMapping );
analysis.registerColumnOptLock( tableMapping, columnMapping.getSelectionExpression(), jdbcValue ); updateAnalysis.registerColumnOptLock( tableMapping, columnMapping.getSelectionExpression(), jdbcValue );
} }
}, },
session session
@ -854,11 +857,14 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple
Object values) { Object values) {
attributeMapping.decompose( attributeMapping.decompose(
values, values,
(jdbcValue, jdbcMapping) -> { 0,
jdbcValueBindings,
tableMapping,
(valueIndex, bindings, table, jdbcValue, jdbcMapping) -> {
if ( !jdbcMapping.isFormula() && jdbcMapping.isUpdateable() ) { if ( !jdbcMapping.isFormula() && jdbcMapping.isUpdateable() ) {
jdbcValueBindings.bindValue( bindings.bindValue(
jdbcValue, jdbcValue,
tableMapping.getTableName(), table.getTableName(),
jdbcMapping.getSelectionExpression(), jdbcMapping.getSelectionExpression(),
ParameterUsage.SET ParameterUsage.SET
); );

View File

@ -298,8 +298,15 @@ public class AnonymousTupleBasicValuedModelPart implements ModelPart, MappingTyp
} }
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public <X, Y> int breakDownJdbcValues(
valueConsumer.consume( domainValue, this ); Object domainValue,
int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) {
valueConsumer.consume( offset, x, y, domainValue, this );
return getJdbcTypeCount();
} }
@Override @Override

View File

@ -401,19 +401,23 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
} }
@Override @Override
public void breakDownJdbcValues( public <X, Y> int breakDownJdbcValues(
Object domainValue, Object domainValue,
JdbcValueConsumer valueConsumer, int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
final Object[] values = (Object[]) domainValue; final Object[] values = (Object[]) domainValue;
assert values.length == modelParts.size(); assert values.length == modelParts.size();
int span = 0;
int i = 0; int i = 0;
for ( ModelPart mapping : modelParts.values() ) { for ( ModelPart mapping : modelParts.values() ) {
final Object attributeValue = values[ i ]; final Object attributeValue = values[ i ];
mapping.breakDownJdbcValues( attributeValue, valueConsumer, session ); span += mapping.breakDownJdbcValues( attributeValue, offset + span, x, y, valueConsumer, session );
i++; i++;
} }
return span;
} }
@Override @Override

View File

@ -550,11 +550,14 @@ public class AnonymousTupleEntityValuedModelPart
} }
@Override @Override
public void breakDownJdbcValues( public <X, Y> int breakDownJdbcValues(
Object domainValue, Object domainValue,
JdbcValueConsumer valueConsumer, int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
delegate.breakDownJdbcValues( domainValue, valueConsumer, session ); return delegate.breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
} }
@Override @Override

View File

@ -374,9 +374,12 @@ public class AnonymousTupleTableGroupProducer implements TableGroupProducer, Map
} }
@Override @Override
public void breakDownJdbcValues( public <X, Y> int breakDownJdbcValues(
Object domainValue, Object domainValue,
JdbcValueConsumer valueConsumer, int offset,
X x,
Y y,
JdbcValueBiConsumer<X, Y> valueConsumer,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
throw new UnsupportedOperationException( "Not yet implemented" ); throw new UnsupportedOperationException( "Not yet implemented" );
} }

View File

@ -40,7 +40,7 @@ public class ColumnValueBindingList extends ArrayList<ColumnValueBinding> implem
} }
@Override @Override
public void consume(Object value, SelectableMapping jdbcValueMapping) { public void consume(int valueIndex, Object value, SelectableMapping jdbcValueMapping) {
final ColumnValueBinding columnValueBinding = createValueBinding( final ColumnValueBinding columnValueBinding = createValueBinding(
jdbcValueMapping.getSelectionExpression(), jdbcValueMapping.getSelectionExpression(),
value == null ? null : jdbcValueMapping.getWriteExpression(), value == null ? null : jdbcValueMapping.getWriteExpression(),

View File

@ -33,7 +33,6 @@ import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentDat
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;
@ -714,34 +713,45 @@ public class ValidityAuditStrategy implements AuditStrategy {
int index, int index,
PreparedStatement statement, PreparedStatement statement,
SessionImplementor session) { SessionImplementor session) {
final MutableInteger position = new MutableInteger( index ); try {
modelPart.breakDownJdbcValues( return modelPart.breakDownJdbcValues(
value, value,
(jdbcValue, jdbcValueMapping) -> { index,
try { statement,
//noinspection unchecked session,
jdbcValueMapping.getJdbcMapping().getJdbcValueBinder().bind( (valueIndex, preparedStatement, sessionImplementor, jdbcValue, jdbcValueMapping) -> {
statement, try {
jdbcValue, //noinspection unchecked
position.getAndIncrease(), jdbcValueMapping.getJdbcMapping().getJdbcValueBinder().bind(
session preparedStatement,
); jdbcValue,
} valueIndex,
catch (SQLException e) { sessionImplementor
throw session.getJdbcServices().getSqlExceptionHelper().convert( );
e, }
String.format( catch (SQLException e) {
Locale.ROOT, throw new NestedRuntimeException( e );
"Error binding JDBC value relative to `%s`", }
modelPart.getNavigableRole().getFullPath() },
) session
); );
} }
}, catch (NestedRuntimeException e) {
session throw session.getJdbcServices().getSqlExceptionHelper().convert(
); (SQLException) e.getCause(),
String.format(
Locale.ROOT,
"Error binding JDBC value relative to `%s`",
modelPart.getNavigableRole().getFullPath()
)
);
}
}
return modelPart.getJdbcTypeCount(); static class NestedRuntimeException extends RuntimeException {
public NestedRuntimeException(SQLException cause) {
super( cause );
}
} }
} }
} }