HHH-16372 Fix NPEs in some Bindable implementations that operate on values
This commit is contained in:
parent
7f7e4b5f6a
commit
71541679e8
|
@ -88,11 +88,6 @@ public abstract class AbstractCompositeIdentifierMapping
|
|||
return getPartMappingType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaType<?> getJavaType() {
|
||||
return getPartMappingType().getMappedJavaType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainingTableExpression() {
|
||||
return tableExpression;
|
||||
|
@ -188,6 +183,13 @@ public abstract class AbstractCompositeIdentifierMapping
|
|||
int span = 0;
|
||||
final EmbeddableMappingType embeddableTypeDescriptor = getEmbeddableTypeDescriptor();
|
||||
final int size = embeddableTypeDescriptor.getNumberOfAttributeMappings();
|
||||
if ( value == null ) {
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
||||
span += attributeMapping.forEachJdbcValue( null, span + offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
|
@ -212,6 +214,7 @@ public abstract class AbstractCompositeIdentifierMapping
|
|||
span += attributeMapping.forEachJdbcValue( o, span + offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
|
|||
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
||||
import org.hibernate.sql.results.graph.Fetchable;
|
||||
import org.hibernate.sql.results.graph.FetchableContainer;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
/**
|
||||
* Describes the mapping of an embeddable (composite).
|
||||
|
@ -37,6 +38,11 @@ public interface EmbeddableValuedModelPart extends ValuedModelPart, Fetchable, F
|
|||
return getEmbeddableTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
default JavaType<?> getJavaType() {
|
||||
return getEmbeddableTypeDescriptor().getJavaType();
|
||||
}
|
||||
|
||||
@Override
|
||||
default ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||
return getEmbeddableTypeDescriptor().findSubPart( name, treatTargetType );
|
||||
|
@ -83,6 +89,43 @@ public interface EmbeddableValuedModelPart extends ValuedModelPart, Fetchable, F
|
|||
return getEmbeddableTypeDescriptor().forEachJdbcValue( value, offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
default <X, Y> int breakDownJdbcValues(
|
||||
Object domainValue,
|
||||
int offset,
|
||||
X x,
|
||||
Y y,
|
||||
JdbcValueBiConsumer<X, Y> valueConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
return getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
default <X, Y> int decompose(
|
||||
Object domainValue,
|
||||
int offset,
|
||||
X x,
|
||||
Y y,
|
||||
JdbcValueBiConsumer<X, Y> valueConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
return getEmbeddableTypeDescriptor().decompose( domainValue, offset, x, y, valueConsumer, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getNumberOfFetchables() {
|
||||
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||
}
|
||||
|
||||
@Override
|
||||
default Fetchable getFetchable(int position) {
|
||||
return getEmbeddableTypeDescriptor().getFetchable( position );
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getSelectableIndex(String selectableName) {
|
||||
return getEmbeddableTypeDescriptor().getSelectableIndex( selectableName );
|
||||
}
|
||||
|
||||
@Override
|
||||
default SelectableMapping getSelectable(int columnIndex) {
|
||||
return getEmbeddableTypeDescriptor().getSelectable( columnIndex );
|
||||
|
@ -93,6 +136,21 @@ public interface EmbeddableValuedModelPart extends ValuedModelPart, Fetchable, F
|
|||
return getEmbeddableTypeDescriptor().forEachSelectable( offset, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
default void forEachInsertable(SelectableConsumer consumer) {
|
||||
getEmbeddableTypeDescriptor().forEachInsertable( 0, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
default void forEachUpdatable(SelectableConsumer consumer) {
|
||||
getEmbeddableTypeDescriptor().forEachUpdatable( 0, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean hasPartitionedSelectionMapping() {
|
||||
return getEmbeddableTypeDescriptor().hasPartitionedSelectionMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
default <X, Y> int forEachDisassembledJdbcValue(
|
||||
Object value,
|
||||
|
|
|
@ -574,8 +574,35 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
|||
forEachAttributeMapping( consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
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 ) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping attribute = attributeMappings.get( i );
|
||||
span += attribute.breakDownJdbcValues( null, offset + span, x, y, valueConsumer, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping attribute = attributeMappings.get( i );
|
||||
final Object attributeValue = attribute.getValue( domainValue );
|
||||
span += attribute.breakDownJdbcValues( attributeValue, offset + span, x, y, valueConsumer, session );
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
final int size = attributeMappings.size();
|
||||
final Object[] result = new Object[ size ];
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
|
@ -590,11 +617,18 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
|||
@Override
|
||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||
final int size = attributeMappings.size();
|
||||
if ( value == null ) {
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
attributeMappings.get( i ).addToCacheKey( cacheKey, null, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
attributeMapping.addToCacheKey( cacheKey, attributeMapping.getValue( value ), session );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int forEachDisassembledJdbcValue(
|
||||
|
@ -604,12 +638,20 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
|||
Y y,
|
||||
JdbcValuesBiConsumer<X, Y> valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
final Object[] values = (Object[]) value;
|
||||
int span = 0;
|
||||
if ( value == null ) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping mapping = attributeMappings.get( i );
|
||||
span += mapping.forEachDisassembledJdbcValue( null, span + offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Object[] values = (Object[]) value;
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping mapping = attributeMappings.get( i );
|
||||
span += mapping.forEachDisassembledJdbcValue( values[i], span + offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
|
@ -622,7 +664,16 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
|||
JdbcValuesBiConsumer<X, Y> valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
int span = 0;
|
||||
|
||||
if ( value == null ) {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
if ( attributeMapping instanceof PluralAttributeMapping ) {
|
||||
continue;
|
||||
}
|
||||
span += attributeMapping.forEachJdbcValue( null, span + offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||
if ( attributeMapping instanceof PluralAttributeMapping ) {
|
||||
|
@ -631,6 +682,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
|||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
span += attributeMapping.forEachJdbcValue( o, span + offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
|
|
|
@ -326,16 +326,23 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
|
|||
for ( int i = 0; i < attributes.size(); i++ ) {
|
||||
span += attributes.get( i ).breakDownJdbcValues( null, offset + span, x, y, valueConsumer, session );
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
else {
|
||||
assert domainValue instanceof Object[];
|
||||
|
||||
final Object[] values = (Object[]) domainValue;
|
||||
assert values.length == attributes.size();
|
||||
|
||||
for ( int i = 0; i < attributes.size(); i++ ) {
|
||||
span += attributes.get( i ).breakDownJdbcValues( values[ i ], offset + span, x, y, valueConsumer, session );
|
||||
span += attributes.get( i ).breakDownJdbcValues(
|
||||
values[i],
|
||||
offset + span,
|
||||
x,
|
||||
y,
|
||||
valueConsumer,
|
||||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
@ -379,6 +386,9 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
|
|||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
assert value instanceof Object[];
|
||||
|
||||
final Object[] incoming = (Object[]) value;
|
||||
|
@ -396,6 +406,12 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
|
|||
|
||||
@Override
|
||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
for ( int i = 0; i < attributes.size(); i++ ) {
|
||||
attributes.get( i ).addToCacheKey( cacheKey, null, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert value instanceof Object[];
|
||||
|
||||
final Object[] values = (Object[]) value;
|
||||
|
@ -405,6 +421,7 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
|
|||
attributes.get( i ).addToCacheKey( cacheKey, values[i], session );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int forEachDisassembledJdbcValue(
|
||||
|
@ -414,14 +431,36 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
|
|||
Y y,
|
||||
JdbcValuesBiConsumer<X, Y> valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
int span = 0;
|
||||
if ( value == null ) {
|
||||
for ( int i = 0; i < attributes.size(); i++ ) {
|
||||
final SingularAttributeMapping attribute = attributes.get( i );
|
||||
span += attribute.forEachDisassembledJdbcValue(
|
||||
null,
|
||||
span + offset,
|
||||
x,
|
||||
y,
|
||||
valuesConsumer,
|
||||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert value instanceof Object[];
|
||||
|
||||
final Object[] incoming = (Object[]) value;
|
||||
assert incoming.length == attributes.size();
|
||||
int span = 0;
|
||||
for ( int i = 0; i < attributes.size(); i++ ) {
|
||||
final SingularAttributeMapping attribute = attributes.get( i );
|
||||
span += attribute.forEachDisassembledJdbcValue( incoming[ i ], span + offset, x, y, valuesConsumer, session );
|
||||
span += attribute.forEachDisassembledJdbcValue(
|
||||
incoming[i],
|
||||
span + offset,
|
||||
x,
|
||||
y,
|
||||
valuesConsumer,
|
||||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
@ -434,16 +473,24 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
|
|||
Y y,
|
||||
JdbcValuesBiConsumer<X, Y> valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
int span = 0;
|
||||
if ( value == null ) {
|
||||
for ( int i = 0; i < attributes.size(); i++ ) {
|
||||
final SingularAttributeMapping attribute = attributes.get( i );
|
||||
span += attribute.forEachJdbcValue( null, span + offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert value instanceof Object[];
|
||||
|
||||
final Object[] incoming = (Object[]) value;
|
||||
assert incoming.length == attributes.size();
|
||||
|
||||
int span = 0;
|
||||
for ( int i = 0; i < attributes.size(); i++ ) {
|
||||
final SingularAttributeMapping attribute = attributes.get( i );
|
||||
span += attribute.forEachJdbcValue( incoming[i], span + offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
|
|
|
@ -240,9 +240,10 @@ public class DiscriminatedAssociationAttributeMapping
|
|||
@Override
|
||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
return ;
|
||||
cacheKey.addValue( null );
|
||||
cacheKey.addHashCode( 0 );
|
||||
}
|
||||
|
||||
else {
|
||||
final EntityMappingType concreteMappingType = determineConcreteType( value, session );
|
||||
|
||||
final Object discriminator = discriminatorMapping
|
||||
|
@ -253,6 +254,7 @@ public class DiscriminatedAssociationAttributeMapping
|
|||
final EntityIdentifierMapping identifierMapping = concreteMappingType.getIdentifierMapping();
|
||||
identifierMapping.addToCacheKey( cacheKey, identifierMapping.getIdentifier( value ), session );
|
||||
}
|
||||
}
|
||||
|
||||
private EntityMappingType determineConcreteType(Object entity, SharedSessionContractImplementor session) {
|
||||
final String entityName;
|
||||
|
@ -290,7 +292,23 @@ public class DiscriminatedAssociationAttributeMapping
|
|||
Y y,
|
||||
JdbcValuesBiConsumer<X, Y> valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
if ( value != null ) {
|
||||
if ( value == null ) {
|
||||
valuesConsumer.consume(
|
||||
offset,
|
||||
x,
|
||||
y,
|
||||
null,
|
||||
discriminatorMapping.getDiscriminatorPart().getJdbcMapping()
|
||||
);
|
||||
valuesConsumer.consume(
|
||||
offset + 1,
|
||||
x,
|
||||
y,
|
||||
null,
|
||||
discriminatorMapping.getKeyPart().getJdbcMapping()
|
||||
);
|
||||
}
|
||||
else {
|
||||
if ( value.getClass().isArray() ) {
|
||||
final Object[] values = (Object[]) value;
|
||||
valuesConsumer.consume(
|
||||
|
|
|
@ -184,53 +184,6 @@ public class EmbeddedAttributeMapping
|
|||
return parentInjectionAttributePropertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Object value1, Object value2) {
|
||||
return super.compare( value1, value2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelectable(int offset, SelectableConsumer consumer) {
|
||||
return getEmbeddableTypeDescriptor().forEachSelectable( offset, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachInsertable(SelectableConsumer consumer) {
|
||||
getEmbeddableTypeDescriptor().forEachInsertable( 0, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachUpdatable(SelectableConsumer consumer) {
|
||||
getEmbeddableTypeDescriptor().forEachUpdatable( 0, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int breakDownJdbcValues(
|
||||
Object domainValue,
|
||||
int offset,
|
||||
X x,
|
||||
Y y,
|
||||
JdbcValueBiConsumer<X, Y> valueConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
return getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int decompose(
|
||||
Object domainValue,
|
||||
int offset,
|
||||
X x,
|
||||
Y y,
|
||||
JdbcValueBiConsumer<X, Y> valueConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
return getEmbeddableTypeDescriptor().decompose( domainValue, offset, x, y, valueConsumer, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPartitionedSelectionMapping() {
|
||||
return getEmbeddableTypeDescriptor().hasPartitionedSelectionMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
|
@ -343,20 +296,6 @@ public class EmbeddedAttributeMapping
|
|||
return new SqlTuple( columnReferences, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelPart findSubPart(
|
||||
String name,
|
||||
EntityMappingType treatTargetType) {
|
||||
return getMappedType().findSubPart( name, treatTargetType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSubParts(
|
||||
Consumer<ModelPart> consumer,
|
||||
EntityMappingType treatTargetType) {
|
||||
getMappedType().visitSubParts( consumer, treatTargetType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableGroupJoin createTableGroupJoin(
|
||||
NavigablePath navigablePath,
|
||||
|
@ -400,21 +339,6 @@ public class EmbeddedAttributeMapping
|
|||
return getAttributeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfFetchables() {
|
||||
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fetchable getFetchable(int position) {
|
||||
return getEmbeddableTypeDescriptor().getFetchable( position );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelectableIndex(String selectableName) {
|
||||
return getEmbeddableTypeDescriptor().getSelectableIndex( selectableName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EmbeddedAttributeMapping(" + navigableRole + ")@" + System.identityHashCode( this );
|
||||
|
|
|
@ -297,11 +297,6 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
|
|||
embeddableMappingType.applySqlSelections( navigablePath, tableGroup, creationState, selectionConsumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaType<?> getJavaType() {
|
||||
return getEmbeddableTypeDescriptor().getJavaType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaType<?> getExpressibleJavaType() {
|
||||
return getJavaType();
|
||||
|
@ -317,32 +312,6 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
|
|||
return collectionDescriptor.getAttributeMapping().findContainingEntityMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfFetchables() {
|
||||
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fetchable getFetchable(int position) {
|
||||
return getEmbeddableTypeDescriptor().getFetchable( position );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelectable(int offset, SelectableConsumer consumer) {
|
||||
return getEmbeddableTypeDescriptor().forEachSelectable( offset, consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int breakDownJdbcValues(
|
||||
Object domainValue,
|
||||
int offset,
|
||||
X x,
|
||||
Y y,
|
||||
JdbcValueBiConsumer<X, Y> valueConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
return getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchStyle getStyle() {
|
||||
return FetchStyle.JOIN;
|
||||
|
@ -353,9 +322,4 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
|
|||
return FetchTiming.IMMEDIATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPartitionedSelectionMapping() {
|
||||
return getEmbeddableTypeDescriptor().hasPartitionedSelectionMapping();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
@ -110,17 +109,6 @@ public class EmbeddedIdentifierMappingImpl
|
|||
return name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getNumberOfFetchables() {
|
||||
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fetchable getFetchable(int position) {
|
||||
return getEmbeddableTypeDescriptor().getFetchable( position );
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyAccess getPropertyAccess() {
|
||||
return propertyAccess;
|
||||
|
@ -131,32 +119,4 @@ public class EmbeddedIdentifierMappingImpl
|
|||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int breakDownJdbcValues(
|
||||
Object domainValue,
|
||||
int offset,
|
||||
X x,
|
||||
Y y,
|
||||
JdbcValueBiConsumer<X, Y> valueConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
return getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, offset, x, y, valueConsumer, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int forEachDisassembledJdbcValue(
|
||||
Object value,
|
||||
int offset,
|
||||
X x,
|
||||
Y y,
|
||||
JdbcValuesBiConsumer<X, Y> valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
return getEmbeddableTypeDescriptor().forEachDisassembledJdbcValue(
|
||||
value,
|
||||
offset,
|
||||
x,
|
||||
y,
|
||||
valuesConsumer,
|
||||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.cache.MutableCacheKeyBuilder;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
|
@ -288,49 +286,6 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
|||
return idMapping.findContainingEntityMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int breakDownJdbcValues(
|
||||
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 );
|
||||
span += attribute.breakDownJdbcValues( attributeValue, offset + span, x, y, valueConsumer, session );
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
// todo (6.0) : reduce to-one values to id here?
|
||||
final Object[] result = new Object[ getNumberOfAttributeMappings() ];
|
||||
for ( int i = 0; i < result.length; i++ ) {
|
||||
final AttributeMapping attributeMapping = getAttributeMapping( i );
|
||||
Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
result[i] = attributeMapping.disassemble( o, session );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
return;
|
||||
}
|
||||
final Serializable[] result = new Serializable[ getNumberOfAttributeMappings() ];
|
||||
for ( int i = 0; i < result.length; i++ ) {
|
||||
final AttributeMapping attributeMapping = getAttributeMapping( i );
|
||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
attributeMapping.addToCacheKey( cacheKey, o, session );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int forEachDisassembledJdbcValue(
|
||||
Object value,
|
||||
|
|
|
@ -158,22 +158,6 @@ public class VirtualIdEmbeddable extends AbstractEmbeddableMapping implements Id
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int breakDownJdbcValues(
|
||||
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 );
|
||||
span += attribute.breakDownJdbcValues( attributeValue, offset + span, x, y, valueConsumer, session );
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int decompose(
|
||||
Object domainValue,
|
||||
|
|
|
@ -34,6 +34,9 @@ public class TupleMappingModelExpressible implements MappingModelExpressible {
|
|||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
final Object[] disassembled = new Object[components.length];
|
||||
final Object[] array = (Object[]) value;
|
||||
for ( int i = 0; i < components.length; i++ ) {
|
||||
|
@ -45,10 +48,15 @@ public class TupleMappingModelExpressible implements MappingModelExpressible {
|
|||
@Override
|
||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
return;
|
||||
}
|
||||
for ( int i = 0; i < components.length; i++ ) {
|
||||
components[i].addToCacheKey( cacheKey, value, session );
|
||||
components[i].addToCacheKey( cacheKey, null, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Object[] array = (Object[]) value;
|
||||
for ( int i = 0; i < components.length; i++ ) {
|
||||
components[i].addToCacheKey( cacheKey, array[i], session );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,10 +68,31 @@ public class TupleMappingModelExpressible implements MappingModelExpressible {
|
|||
Y y,
|
||||
JdbcValuesBiConsumer<X, Y> valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
final Object[] values = (Object[]) value;
|
||||
int span = 0;
|
||||
if ( value == null ) {
|
||||
for ( int i = 0; i < components.length; i++ ) {
|
||||
span += components[i].forEachDisassembledJdbcValue( values[i], span + offset, x, y, valuesConsumer, session );
|
||||
span += components[i].forEachDisassembledJdbcValue(
|
||||
null,
|
||||
span + offset,
|
||||
x,
|
||||
y,
|
||||
valuesConsumer,
|
||||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Object[] values = (Object[]) value;
|
||||
for ( int i = 0; i < components.length; i++ ) {
|
||||
span += components[i].forEachDisassembledJdbcValue(
|
||||
values[i],
|
||||
span + offset,
|
||||
x,
|
||||
y,
|
||||
valuesConsumer,
|
||||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
@ -76,8 +105,19 @@ public class TupleMappingModelExpressible implements MappingModelExpressible {
|
|||
Y y,
|
||||
JdbcValuesBiConsumer<X, Y> valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
final Object[] values = (Object[]) value;
|
||||
int span = 0;
|
||||
if ( value == null ) {
|
||||
for ( int i = 0; i < components.length; i++ ) {
|
||||
span += components[i].forEachDisassembledJdbcValue(
|
||||
components[i].disassemble( null, session ),
|
||||
span + offset,
|
||||
x, y, valuesConsumer,
|
||||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Object[] values = (Object[]) value;
|
||||
for ( int i = 0; i < components.length; i++ ) {
|
||||
span += components[i].forEachDisassembledJdbcValue(
|
||||
components[i].disassemble( values[i], session ),
|
||||
|
@ -86,6 +126,7 @@ public class TupleMappingModelExpressible implements MappingModelExpressible {
|
|||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.hibernate.sql.results.graph.DomainResultCreationState;
|
|||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchOptions;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.graph.Fetchable;
|
||||
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableResultImpl;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
|
@ -67,19 +68,21 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
|
||||
private static final FetchOptions FETCH_OPTIONS = FetchOptions.valueOf( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
||||
|
||||
private final Map<String, ModelPart> modelParts;
|
||||
private final Map<String, ModelPart> modelPartMap;
|
||||
private final ModelPart[] modelParts;
|
||||
private final DomainType<?> domainType;
|
||||
private final String componentName;
|
||||
private final EmbeddableValuedModelPart existingModelPartContainer;
|
||||
private final int fetchableIndex;
|
||||
|
||||
public AnonymousTupleEmbeddableValuedModelPart(
|
||||
Map<String, ModelPart> modelParts,
|
||||
Map<String, ModelPart> modelPartMap,
|
||||
DomainType<?> domainType,
|
||||
String componentName,
|
||||
EmbeddableValuedModelPart existingModelPartContainer,
|
||||
int fetchableIndex) {
|
||||
this.modelParts = modelParts;
|
||||
this.modelPartMap = modelPartMap;
|
||||
this.modelParts = modelPartMap.values().toArray( new ModelPart[0] );
|
||||
this.domainType = domainType;
|
||||
this.componentName = componentName;
|
||||
this.existingModelPartContainer = existingModelPartContainer;
|
||||
|
@ -88,12 +91,21 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
|
||||
@Override
|
||||
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||
return modelParts.get( name );
|
||||
return modelPartMap.get( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachSubPart(IndexedConsumer<ModelPart> consumer, EntityMappingType treatTarget) {
|
||||
for ( int i = 0; i < modelParts.length; i++ ) {
|
||||
consumer.accept( i, modelParts[i] );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSubParts(Consumer<ModelPart> consumer, EntityMappingType treatTargetType) {
|
||||
modelParts.values().forEach( consumer );
|
||||
for ( int i = 0; i < modelParts.length; i++ ) {
|
||||
consumer.accept( modelParts[i] );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -148,7 +160,7 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
|
||||
@Override
|
||||
public int getNumberOfAttributeMappings() {
|
||||
return modelParts.size();
|
||||
return modelParts.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -166,6 +178,17 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int decompose(
|
||||
Object domainValue,
|
||||
int offset,
|
||||
X x,
|
||||
Y y,
|
||||
JdbcValueBiConsumer<X, Y> valueConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getValues(Object instance) {
|
||||
return existingModelPartContainer.getEmbeddableTypeDescriptor()
|
||||
|
@ -192,6 +215,11 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
.setValue( instance, value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelectableIndex(String selectableName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectableMapping getSelectable(int columnIndex) {
|
||||
final List<SelectableMapping> results = new ArrayList<>();
|
||||
|
@ -199,6 +227,16 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
return results.get( columnIndex );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fetchable getFetchable(int position) {
|
||||
return (Fetchable) modelParts[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcMapping getJdbcMapping(int index) {
|
||||
return getSelectable( index ).getJdbcMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JdbcMapping> getJdbcMappings() {
|
||||
final List<JdbcMapping> results = new ArrayList<>();
|
||||
|
@ -214,12 +252,22 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
@Override
|
||||
public int forEachSelectable(int offset, SelectableConsumer consumer) {
|
||||
int span = 0;
|
||||
for ( ModelPart mapping : modelParts.values() ) {
|
||||
for ( ModelPart mapping : modelParts ) {
|
||||
span += mapping.forEachSelectable( offset + span, consumer );
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachInsertable(int offset, SelectableConsumer consumer) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachUpdatable(int offset, SelectableConsumer consumer) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainingTableExpression() {
|
||||
return "";
|
||||
|
@ -234,7 +282,7 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( getJdbcTypeCount() );
|
||||
final NavigablePath navigablePath = tableGroup.getNavigablePath().append( componentName );
|
||||
final TableReference tableReference = tableGroup.resolveTableReference( navigablePath, getContainingTableExpression() );
|
||||
for ( ModelPart modelPart : modelParts.values() ) {
|
||||
for ( ModelPart modelPart : modelParts ) {
|
||||
modelPart.forEachSelectable(
|
||||
(columnIndex, selection) -> {
|
||||
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
|
||||
|
@ -339,7 +387,7 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
|
||||
@Override
|
||||
public int getNumberOfFetchables() {
|
||||
return modelParts.size();
|
||||
return modelParts.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -376,7 +424,7 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
DomainResultCreationState creationState) {
|
||||
for ( ModelPart mapping : modelParts.values() ) {
|
||||
for ( ModelPart mapping : modelParts ) {
|
||||
mapping.applySqlSelections( navigablePath, tableGroup, creationState );
|
||||
}
|
||||
}
|
||||
|
@ -387,7 +435,7 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
TableGroup tableGroup,
|
||||
DomainResultCreationState creationState,
|
||||
BiConsumer<SqlSelection, JdbcMapping> selectionConsumer) {
|
||||
for ( ModelPart mapping : modelParts.values() ) {
|
||||
for ( ModelPart mapping : modelParts ) {
|
||||
mapping.applySqlSelections( navigablePath, tableGroup, creationState, selectionConsumer );
|
||||
}
|
||||
}
|
||||
|
@ -400,27 +448,33 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
Y y,
|
||||
JdbcValueBiConsumer<X, Y> valueConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
final Object[] values = (Object[]) domainValue;
|
||||
assert values.length == modelParts.size();
|
||||
int span = 0;
|
||||
int i = 0;
|
||||
for ( ModelPart mapping : modelParts.values() ) {
|
||||
if ( domainValue == null ) {
|
||||
for ( ModelPart mapping : modelParts ) {
|
||||
span += mapping.breakDownJdbcValues( null, offset + span, x, y, valueConsumer, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Object[] values = (Object[]) domainValue;
|
||||
assert values.length == modelParts.length;
|
||||
for ( int i = 0; i < modelParts.length; i++ ) {
|
||||
final Object attributeValue = values[i];
|
||||
span += mapping.breakDownJdbcValues( attributeValue, offset + span, x, y, valueConsumer, session );
|
||||
i++;
|
||||
span += modelParts[i].breakDownJdbcValues( attributeValue, offset + span, x, y, valueConsumer, session );
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
final Object[] values = (Object[]) value;
|
||||
final Object[] result = new Object[ modelParts.size() ];
|
||||
int i = 0;
|
||||
for ( ModelPart mapping : modelParts.values() ) {
|
||||
final Object[] result = new Object[ modelParts.length ];
|
||||
for ( int i = 0; i < modelParts.length; i++ ) {
|
||||
Object o = values[i];
|
||||
result[i] = mapping.disassemble( o, session );
|
||||
i++;
|
||||
result[i] = modelParts[i].disassemble( o, session );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -428,13 +482,20 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
|
||||
@Override
|
||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
for ( ModelPart mapping : modelParts ) {
|
||||
mapping.addToCacheKey( cacheKey, null, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Object[] values = (Object[]) value;
|
||||
int i = 0;
|
||||
for ( ModelPart mapping : modelParts.values() ) {
|
||||
for ( ModelPart mapping : modelParts ) {
|
||||
mapping.addToCacheKey( cacheKey, values[i], session );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X, Y> int forEachDisassembledJdbcValue(
|
||||
|
@ -444,12 +505,17 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
Y y,
|
||||
JdbcValuesBiConsumer<X, Y> valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
final Object[] values = (Object[]) value;
|
||||
int span = 0;
|
||||
int i = 0;
|
||||
for ( ModelPart mapping : modelParts.values() ) {
|
||||
span += mapping.forEachDisassembledJdbcValue( values[i], span + offset, x, y, valuesConsumer, session );
|
||||
i++;
|
||||
if ( value == null ) {
|
||||
for ( ModelPart mapping : modelParts ) {
|
||||
span += mapping.forEachDisassembledJdbcValue( null, span + offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Object[] values = (Object[]) value;
|
||||
for ( int i = 0; i < modelParts.length; i++ ) {
|
||||
span += modelParts[i].forEachDisassembledJdbcValue( values[i], span + offset, x, y, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
@ -462,13 +528,18 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
Y y,
|
||||
JdbcValuesBiConsumer<X, Y> consumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
final Object[] values = (Object[]) value;
|
||||
int span = 0;
|
||||
int i = 0;
|
||||
for ( ModelPart attributeMapping : modelParts.values() ) {
|
||||
if ( value == null ) {
|
||||
for ( ModelPart mapping : modelParts ) {
|
||||
span += mapping.forEachJdbcValue( null, span + offset, x, y, consumer, session );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Object[] values = (Object[]) value;
|
||||
for ( int i = 0; i < modelParts.length; i++ ) {
|
||||
final Object o = values[i];
|
||||
span += attributeMapping.forEachJdbcValue( o, span + offset, x, y, consumer, session );
|
||||
i++;
|
||||
span += modelParts[i].forEachJdbcValue( o, span + offset, x, y, consumer, session );
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
@ -476,7 +547,7 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
|||
@Override
|
||||
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
|
||||
int span = 0;
|
||||
for ( ModelPart attributeMapping : modelParts.values() ) {
|
||||
for ( ModelPart attributeMapping : modelParts ) {
|
||||
span += attributeMapping.forEachJdbcType( span + offset, action );
|
||||
}
|
||||
return span;
|
||||
|
|
Loading…
Reference in New Issue