HHH-15636 Indexed Fetchable access via IndexedConsumer and by position and get rid of some capturing lambdas
This commit is contained in:
parent
53076f3029
commit
2f4712909a
|
@ -146,9 +146,9 @@ public class EnhancementAsProxyLazinessInterceptor extends AbstractLazyLoadInter
|
||||||
if ( writtenValues != null ) {
|
if ( writtenValues != null ) {
|
||||||
// here is the replaying of the explicitly set values we prepared above
|
// here is the replaying of the explicitly set values we prepared above
|
||||||
for ( String writtenFieldName : writtenFieldNames ) {
|
for ( String writtenFieldName : writtenFieldNames ) {
|
||||||
List<AttributeMapping> attributeMappings = entityPersister.getAttributeMappings();
|
final int size = entityPersister.getNumberOfAttributeMappings();
|
||||||
for ( int index = 0; index < attributeMappings.size(); index++ ) {
|
for ( int index = 0; index < size; index++ ) {
|
||||||
if ( writtenFieldName.contains( attributeMappings.get( index ).getAttributeName() ) ) {
|
if ( writtenFieldName.contains( entityPersister.getAttributeMapping( index ).getAttributeName() ) ) {
|
||||||
entityPersister.setValue(
|
entityPersister.setValue(
|
||||||
target,
|
target,
|
||||||
index,
|
index,
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.hibernate.loader.entity.CacheEntityLoaderHelper;
|
||||||
import org.hibernate.loader.entity.CacheEntityLoaderHelper.PersistenceContextEntry;
|
import org.hibernate.loader.entity.CacheEntityLoaderHelper.PersistenceContextEntry;
|
||||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
|
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||||
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.MappingType;
|
import org.hibernate.metamodel.mapping.MappingType;
|
||||||
|
@ -118,9 +119,9 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
||||||
final EntityIdentifierMapping idMapping = persister.getIdentifierMapping();
|
final EntityIdentifierMapping idMapping = persister.getIdentifierMapping();
|
||||||
if ( idMapping instanceof CompositeIdentifierMapping ) {
|
if ( idMapping instanceof CompositeIdentifierMapping ) {
|
||||||
final CompositeIdentifierMapping compositeIdMapping = (CompositeIdentifierMapping) idMapping;
|
final CompositeIdentifierMapping compositeIdMapping = (CompositeIdentifierMapping) idMapping;
|
||||||
final List<AttributeMapping> attributeMappings = compositeIdMapping.getPartMappingType().getAttributeMappings();
|
final EmbeddableMappingType partMappingType = compositeIdMapping.getPartMappingType();
|
||||||
if ( attributeMappings.size() == 1 ) {
|
if ( partMappingType.getNumberOfAttributeMappings() == 1 ) {
|
||||||
final AttributeMapping singleIdAttribute = attributeMappings.get( 0 );
|
final AttributeMapping singleIdAttribute = partMappingType.getAttributeMapping( 0 );
|
||||||
if ( singleIdAttribute.getMappedType() instanceof EntityMappingType ) {
|
if ( singleIdAttribute.getMappedType() instanceof EntityMappingType ) {
|
||||||
final EntityMappingType parentIdTargetMapping = (EntityMappingType) singleIdAttribute.getMappedType();
|
final EntityMappingType parentIdTargetMapping = (EntityMappingType) singleIdAttribute.getMappedType();
|
||||||
final EntityIdentifierMapping parentIdTargetIdMapping = parentIdTargetMapping.getIdentifierMapping();
|
final EntityIdentifierMapping parentIdTargetIdMapping = parentIdTargetMapping.getIdentifierMapping();
|
||||||
|
|
|
@ -54,6 +54,9 @@ import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
|
import org.hibernate.sql.results.graph.FetchableContainer;
|
||||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||||
|
|
||||||
|
@ -99,25 +102,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
null,
|
null,
|
||||||
creationState
|
creationState
|
||||||
),
|
),
|
||||||
(fetchParent, querySpec, creationState) -> {
|
AbstractNaturalIdLoader::visitFetches,
|
||||||
final List<Fetch> fetches = new ArrayList<>( naturalIdMapping.getNaturalIdAttributes().size() );
|
|
||||||
fetchParent.getReferencedMappingContainer().visitFetchables(
|
|
||||||
fetchable -> {
|
|
||||||
final NavigablePath navigablePath = fetchParent.resolveNavigablePath( fetchable );
|
|
||||||
final Fetch fetch = fetchParent.generateFetchableFetch(
|
|
||||||
fetchable,
|
|
||||||
navigablePath,
|
|
||||||
fetchable.getMappedFetchOptions().getTiming(),
|
|
||||||
true,
|
|
||||||
null,
|
|
||||||
creationState
|
|
||||||
);
|
|
||||||
fetches.add( fetch );
|
|
||||||
},
|
|
||||||
entityDescriptor
|
|
||||||
);
|
|
||||||
return fetches;
|
|
||||||
},
|
|
||||||
(statsEnabled) -> {
|
(statsEnabled) -> {
|
||||||
// entityDescriptor().getPreLoadListener().startingLoad( entityDescriptor, naturalIdValue, KeyType.NATURAL_ID, LoadSource.DATABASE );
|
// entityDescriptor().getPreLoadListener().startingLoad( entityDescriptor, naturalIdValue, KeyType.NATURAL_ID, LoadSource.DATABASE );
|
||||||
return statsEnabled ? System.nanoTime() : -1;
|
return statsEnabled ? System.nanoTime() : -1;
|
||||||
|
@ -326,27 +311,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
null,
|
null,
|
||||||
creationState
|
creationState
|
||||||
),
|
),
|
||||||
(fetchParent, querySpec, creationState) -> {
|
AbstractNaturalIdLoader::visitFetches,
|
||||||
final List<Fetch> fetches = new ArrayList<>();
|
|
||||||
|
|
||||||
fetchParent.getReferencedMappingContainer().visitFetchables(
|
|
||||||
(fetchable) -> {
|
|
||||||
final NavigablePath navigablePath = fetchParent.resolveNavigablePath( fetchable );
|
|
||||||
final Fetch fetch = fetchParent.generateFetchableFetch(
|
|
||||||
fetchable,
|
|
||||||
navigablePath,
|
|
||||||
fetchable.getMappedFetchOptions().getTiming(),
|
|
||||||
true,
|
|
||||||
null,
|
|
||||||
creationState
|
|
||||||
);
|
|
||||||
fetches.add( fetch );
|
|
||||||
},
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
return fetches;
|
|
||||||
},
|
|
||||||
(statsEnabled) -> {
|
(statsEnabled) -> {
|
||||||
// entityDescriptor().getPreLoadListener().startingLoad( entityDescriptor, naturalIdValue, KeyType.NATURAL_ID, LoadSource.DATABASE );
|
// entityDescriptor().getPreLoadListener().startingLoad( entityDescriptor, naturalIdValue, KeyType.NATURAL_ID, LoadSource.DATABASE );
|
||||||
return statsEnabled ? System.nanoTime() : -1L;
|
return statsEnabled ? System.nanoTime() : -1L;
|
||||||
|
@ -455,4 +420,27 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
|
|
||||||
return results.get( 0 );
|
return results.get( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<Fetch> visitFetches(
|
||||||
|
FetchParent fetchParent,
|
||||||
|
QuerySpec querySpec,
|
||||||
|
LoaderSqlAstCreationState creationState) {
|
||||||
|
final FetchableContainer fetchableContainer = fetchParent.getReferencedMappingContainer();
|
||||||
|
final int size = fetchableContainer.getNumberOfFetchables();
|
||||||
|
final List<Fetch> fetches = new ArrayList<>( size );
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
final Fetchable fetchable = fetchableContainer.getFetchable( i );
|
||||||
|
final NavigablePath navigablePath = fetchParent.resolveNavigablePath( fetchable );
|
||||||
|
final Fetch fetch = fetchParent.generateFetchableFetch(
|
||||||
|
fetchable,
|
||||||
|
navigablePath,
|
||||||
|
fetchable.getMappedFetchOptions().getTiming(),
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
creationState
|
||||||
|
);
|
||||||
|
fetches.add( fetch );
|
||||||
|
}
|
||||||
|
return fetches;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -674,11 +674,15 @@ public class LoaderSelectBuilder {
|
||||||
|
|
||||||
final FetchableContainer referencedMappingContainer = fetchParent.getReferencedMappingContainer();
|
final FetchableContainer referencedMappingContainer = fetchParent.getReferencedMappingContainer();
|
||||||
if ( fetchParent.getNavigablePath().getParent() != null ) {
|
if ( fetchParent.getNavigablePath().getParent() != null ) {
|
||||||
referencedMappingContainer.visitKeyFetchables(
|
final int size = referencedMappingContainer.getNumberOfKeyFetchables();
|
||||||
fetchable -> processor.accept( fetchable, true ), null );
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
processor.accept( referencedMappingContainer.getKeyFetchable( i ), true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final int size = referencedMappingContainer.getNumberOfFetchables();
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
processor.accept( referencedMappingContainer.getFetchable( i ), false );
|
||||||
}
|
}
|
||||||
referencedMappingContainer.visitFetchables(
|
|
||||||
fetchable -> processor.accept( fetchable, false ), null );
|
|
||||||
return fetches;
|
return fetches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,9 +194,10 @@ public abstract class AbstractCompositeIdentifierMapping
|
||||||
JdbcValuesConsumer valuesConsumer,
|
JdbcValuesConsumer valuesConsumer,
|
||||||
SharedSessionContractImplementor session) {
|
SharedSessionContractImplementor session) {
|
||||||
int span = 0;
|
int span = 0;
|
||||||
final List<AttributeMapping> attributeMappings = getEmbeddableTypeDescriptor().getAttributeMappings();
|
final EmbeddableMappingType embeddableTypeDescriptor = getEmbeddableTypeDescriptor();
|
||||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
final int size = embeddableTypeDescriptor.getNumberOfAttributeMappings();
|
||||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
||||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||||
if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
||||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
|
@ -466,6 +467,11 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
|
||||||
return getEntityPersister().getNumberOfFetchables();
|
return getEntityPersister().getNumberOfFetchables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Fetchable getFetchable(int position) {
|
||||||
|
return getEntityPersister().getFetchable( position );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void applyDiscriminator(
|
default void applyDiscriminator(
|
||||||
Consumer<Predicate> predicateConsumer,
|
Consumer<Predicate> predicateConsumer,
|
||||||
|
|
|
@ -134,13 +134,17 @@ public class MappingModelHelper {
|
||||||
else if ( attribute1 instanceof EmbeddableValuedModelPart ) {
|
else if ( attribute1 instanceof EmbeddableValuedModelPart ) {
|
||||||
final EmbeddableValuedModelPart embedded1 = (EmbeddableValuedModelPart) attribute1;
|
final EmbeddableValuedModelPart embedded1 = (EmbeddableValuedModelPart) attribute1;
|
||||||
final EmbeddableValuedModelPart embedded2 = (EmbeddableValuedModelPart) attribute2;
|
final EmbeddableValuedModelPart embedded2 = (EmbeddableValuedModelPart) attribute2;
|
||||||
final List<AttributeMapping> attrs1 = embedded1.getEmbeddableTypeDescriptor().getAttributeMappings();
|
final EmbeddableMappingType embeddableTypeDescriptor1 = embedded1.getEmbeddableTypeDescriptor();
|
||||||
final List<AttributeMapping> attrs2 = embedded2.getEmbeddableTypeDescriptor().getAttributeMappings();
|
final EmbeddableMappingType embeddableTypeDescriptor2 = embedded2.getEmbeddableTypeDescriptor();
|
||||||
if ( attrs1.size() != attrs2.size() ) {
|
final int numberOfAttributeMappings = embeddableTypeDescriptor1.getNumberOfAttributeMappings();
|
||||||
|
if ( numberOfAttributeMappings != embeddableTypeDescriptor2.getNumberOfAttributeMappings() ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for ( int i = 0; i < attrs1.size(); i++ ) {
|
for ( int i = 0; i < numberOfAttributeMappings; i++ ) {
|
||||||
if ( !isCompatibleModelPart( attrs1.get( i ), attrs2.get( i ) ) ) {
|
if ( !isCompatibleModelPart(
|
||||||
|
embeddableTypeDescriptor1.getAttributeMapping( i ),
|
||||||
|
embeddableTypeDescriptor2.getAttributeMapping( i )
|
||||||
|
) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.Filter;
|
import org.hibernate.Filter;
|
||||||
import org.hibernate.loader.ast.spi.Loadable;
|
import org.hibernate.loader.ast.spi.Loadable;
|
||||||
|
import org.hibernate.mapping.IndexedConsumer;
|
||||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.ordering.OrderByFragment;
|
import org.hibernate.metamodel.mapping.ordering.OrderByFragment;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
@ -66,11 +67,51 @@ public interface PluralAttributeMapping
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getNumberOfKeyFetchables() {
|
||||||
|
return getIndexDescriptor() == null ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Fetchable getKeyFetchable(int position) {
|
||||||
|
final CollectionPart indexDescriptor = getIndexDescriptor();
|
||||||
|
if ( indexDescriptor != null && position == 0 ) {
|
||||||
|
return indexDescriptor;
|
||||||
|
}
|
||||||
|
throw new IndexOutOfBoundsException( position );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void visitKeyFetchables(IndexedConsumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
|
final CollectionPart indexDescriptor = getIndexDescriptor();
|
||||||
|
if ( indexDescriptor != null ) {
|
||||||
|
fetchableConsumer.accept( 0, indexDescriptor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void visitFetchables(Consumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
default void visitFetchables(Consumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
fetchableConsumer.accept( getElementDescriptor() );
|
fetchableConsumer.accept( getElementDescriptor() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getNumberOfFetchables() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void visitFetchables(IndexedConsumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
|
fetchableConsumer.accept( 0, getElementDescriptor() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Fetchable getFetchable(int position) {
|
||||||
|
if ( position == 0 ) {
|
||||||
|
return getElementDescriptor();
|
||||||
|
}
|
||||||
|
throw new IndexOutOfBoundsException( position );
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
@Override
|
@Override
|
||||||
default <T> DomainResult<T> createSnapshotDomainResult(
|
default <T> DomainResult<T> createSnapshotDomainResult(
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
import org.hibernate.sql.ast.tree.select.SortSpecification;
|
import org.hibernate.sql.ast.tree.select.SortSpecification;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrea Boriero
|
* @author Andrea Boriero
|
||||||
|
@ -86,13 +87,12 @@ public abstract class AbstractDomainPath implements DomainPath {
|
||||||
final EmbeddableValuedModelPart embeddableValuedModelPart = (EmbeddableValuedModelPart) referenceModelPart;
|
final EmbeddableValuedModelPart embeddableValuedModelPart = (EmbeddableValuedModelPart) referenceModelPart;
|
||||||
if ( embeddableValuedModelPart.getFetchableName()
|
if ( embeddableValuedModelPart.getFetchableName()
|
||||||
.equals( modelPartName ) || ELEMENT_TOKEN.equals( modelPartName ) ) {
|
.equals( modelPartName ) || ELEMENT_TOKEN.equals( modelPartName ) ) {
|
||||||
final List<Expression> expressions = new ArrayList<>( embeddableValuedModelPart.getNumberOfFetchables() );
|
final int size = embeddableValuedModelPart.getNumberOfFetchables();
|
||||||
embeddableValuedModelPart.visitFetchables(
|
final List<Expression> expressions = new ArrayList<>( size );
|
||||||
fetchable -> {
|
for ( int i = 0; i < size; i++ ) {
|
||||||
expressions.add( resolve( fetchable, ast, tableGroup, modelPartName, creationState ) );
|
final Fetchable fetchable = embeddableValuedModelPart.getFetchable( i );
|
||||||
},
|
expressions.add( resolve( fetchable, ast, tableGroup, modelPartName, creationState ) );
|
||||||
null
|
}
|
||||||
);
|
|
||||||
return new SqlTuple( expressions, embeddableValuedModelPart );
|
return new SqlTuple( expressions, embeddableValuedModelPart );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -136,7 +136,8 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
MappingModelCreationProcess creationProcess,
|
MappingModelCreationProcess creationProcess,
|
||||||
ManagedMappingType declaringType,
|
ManagedMappingType declaringType,
|
||||||
List<? extends AttributeMapping> attributeMappings) {
|
List<? extends AttributeMapping> attributeMappings) {
|
||||||
if ( inverseMappingType.getAttributeMappings().isEmpty() ) {
|
final int size = inverseMappingType.getNumberOfAttributeMappings();
|
||||||
|
if ( size == 0 ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
|
@ -145,7 +146,8 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
mappings.clear();
|
mappings.clear();
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
// We copy the attributes from the inverse mappings and replace the selection mappings
|
// We copy the attributes from the inverse mappings and replace the selection mappings
|
||||||
for ( AttributeMapping attributeMapping : inverseMappingType.getAttributeMappings() ) {
|
for ( int j = 0; j < size; j++ ) {
|
||||||
|
AttributeMapping attributeMapping = inverseMappingType.getAttributeMapping( j );
|
||||||
if ( attributeMapping instanceof BasicAttributeMapping ) {
|
if ( attributeMapping instanceof BasicAttributeMapping ) {
|
||||||
final BasicAttributeMapping original = (BasicAttributeMapping) attributeMapping;
|
final BasicAttributeMapping original = (BasicAttributeMapping) attributeMapping;
|
||||||
final SelectableMapping selectableMapping = selectableMappings.getSelectable( currentIndex );
|
final SelectableMapping selectableMapping = selectableMappings.getSelectable( currentIndex );
|
||||||
|
@ -161,7 +163,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
else if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
else if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
||||||
final ToOneAttributeMapping original = (ToOneAttributeMapping) attributeMapping;
|
final ToOneAttributeMapping original = (ToOneAttributeMapping) attributeMapping;
|
||||||
ForeignKeyDescriptor foreignKeyDescriptor = original.getForeignKeyDescriptor();
|
ForeignKeyDescriptor foreignKeyDescriptor = original.getForeignKeyDescriptor();
|
||||||
if ( foreignKeyDescriptor==null ) {
|
if ( foreignKeyDescriptor == null ) {
|
||||||
// This is expected to happen when processing a
|
// This is expected to happen when processing a
|
||||||
// PostInitCallbackEntry because the callbacks
|
// PostInitCallbackEntry because the callbacks
|
||||||
// are not ordered. The exception is caught in
|
// are not ordered. The exception is caught in
|
||||||
|
@ -191,7 +193,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
}
|
}
|
||||||
else if ( attributeMapping instanceof EmbeddableValuedModelPart ) {
|
else if ( attributeMapping instanceof EmbeddableValuedModelPart ) {
|
||||||
final SelectableMapping[] subMappings = new SelectableMapping[attributeMapping.getJdbcTypeCount()];
|
final SelectableMapping[] subMappings = new SelectableMapping[attributeMapping.getJdbcTypeCount()];
|
||||||
for (int i = 0; i < subMappings.length; i++) {
|
for ( int i = 0; i < subMappings.length; i++ ) {
|
||||||
subMappings[i] = selectableMappings.getSelectable( currentIndex++ );
|
subMappings[i] = selectableMappings.getSelectable( currentIndex++ );
|
||||||
}
|
}
|
||||||
attributeMapping = MappingModelCreationHelper.createInverseModelPart(
|
attributeMapping = MappingModelCreationHelper.createInverseModelPart(
|
||||||
|
|
|
@ -422,6 +422,11 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
|
||||||
return attributes.size();
|
return attributes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return attributes.get( position );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||||
for ( int i = 0; i < attributes.size(); i++ ) {
|
for ( int i = 0; i < attributes.size(); i++ ) {
|
||||||
|
|
|
@ -184,6 +184,17 @@ public class DiscriminatedAssociationAttributeMapping
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
switch ( position ) {
|
||||||
|
case 0:
|
||||||
|
return getDiscriminatorPart();
|
||||||
|
case 1:
|
||||||
|
return getKeyPart();
|
||||||
|
}
|
||||||
|
throw new IndexOutOfBoundsException(position);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getJdbcTypeCount() {
|
public int getJdbcTypeCount() {
|
||||||
return getDiscriminatorPart().getJdbcTypeCount() + getKeyPart().getJdbcTypeCount();
|
return getDiscriminatorPart().getJdbcTypeCount() + getKeyPart().getJdbcTypeCount();
|
||||||
|
@ -313,6 +324,12 @@ public class DiscriminatedAssociationAttributeMapping
|
||||||
fetchableConsumer.accept( getKeyPart() );
|
fetchableConsumer.accept( getKeyPart() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitFetchables(IndexedConsumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
|
fetchableConsumer.accept( 0, getDiscriminatorPart() );
|
||||||
|
fetchableConsumer.accept( 1, getKeyPart() );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||||
return discriminatorMapping.findSubPart( name, treatTargetType );
|
return discriminatorMapping.findSubPart( name, treatTargetType );
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchOptions;
|
import org.hibernate.sql.results.graph.FetchOptions;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
|
@ -212,6 +213,17 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
switch ( position ) {
|
||||||
|
case 0:
|
||||||
|
return getDiscriminatorPart();
|
||||||
|
case 1:
|
||||||
|
return getKeyPart();
|
||||||
|
}
|
||||||
|
throw new IndexOutOfBoundsException(position);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getJdbcTypeCount() {
|
public int getJdbcTypeCount() {
|
||||||
return getDiscriminatorPart().getJdbcTypeCount() + getKeyPart().getJdbcTypeCount();
|
return getDiscriminatorPart().getJdbcTypeCount() + getKeyPart().getJdbcTypeCount();
|
||||||
|
|
|
@ -561,11 +561,24 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
||||||
return attributeMappings.size();
|
return attributeMappings.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return attributeMappings.get( position );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitFetchables(Consumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
public void visitFetchables(Consumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
visitAttributeMappings( fetchableConsumer );
|
visitAttributeMappings( fetchableConsumer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitFetchables(IndexedConsumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
|
final int size = attributeMappings.size();
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
fetchableConsumer.accept( i, attributeMappings.get( i ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SelectableMapping getSelectable(int columnIndex) {
|
public SelectableMapping getSelectable(int columnIndex) {
|
||||||
return getSelectableMappings().getSelectable( columnIndex );
|
return getSelectableMappings().getSelectable( columnIndex );
|
||||||
|
@ -591,33 +604,31 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
||||||
|
final int size = attributeMappings.size();
|
||||||
if ( domainValue instanceof Object[] ) {
|
if ( domainValue instanceof Object[] ) {
|
||||||
final Object[] values = (Object[]) domainValue;
|
final Object[] values = (Object[]) domainValue;
|
||||||
assert values.length == attributeMappings.size();
|
assert values.length == size;
|
||||||
|
|
||||||
for ( int i = 0; i < attributeMappings.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 );
|
attributeMapping.breakDownJdbcValues( attributeValue, valueConsumer, session );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
attributeMappings.forEach(
|
for ( int i = 0; i < size; i++ ) {
|
||||||
(attributeMapping) -> {
|
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||||
final Object attributeValue = attributeMapping.getPropertyAccess().getGetter().get( domainValue );
|
final Object attributeValue = attributeMapping.getPropertyAccess().getGetter().get( domainValue );
|
||||||
attributeMapping.breakDownJdbcValues( attributeValue, valueConsumer, session );
|
attributeMapping.breakDownJdbcValues( attributeValue, valueConsumer, session );
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||||
final List<AttributeMapping> attributeMappings = getAttributeMappings();
|
final Object[] result = new Object[ getNumberOfAttributeMappings() ];
|
||||||
|
for ( int i = 0; i < result.length; i++ ) {
|
||||||
final Object[] result = new Object[ attributeMappings.size() ];
|
final AttributeMapping attributeMapping = getAttributeMapping( i );
|
||||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
|
||||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
|
||||||
Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||||
result[i] = attributeMapping.disassemble( o, session );
|
result[i] = attributeMapping.disassemble( o, session );
|
||||||
}
|
}
|
||||||
|
|
|
@ -351,6 +351,11 @@ public class EmbeddedAttributeMapping
|
||||||
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return getEmbeddableTypeDescriptor().getFetchable( position );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "EmbeddedAttributeMapping(" + navigableRole + ")@" + System.identityHashCode( this );
|
return "EmbeddedAttributeMapping(" + navigableRole + ")@" + System.identityHashCode( this );
|
||||||
|
|
|
@ -49,6 +49,7 @@ import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchOptions;
|
import org.hibernate.sql.results.graph.FetchOptions;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
||||||
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
|
||||||
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableResultImpl;
|
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableResultImpl;
|
||||||
|
@ -328,6 +329,11 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
|
||||||
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return getEmbeddableTypeDescriptor().getFetchable( position );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
||||||
getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, valueConsumer, session );
|
getEmbeddableTypeDescriptor().breakDownJdbcValues( domainValue, valueConsumer, session );
|
||||||
|
|
|
@ -92,8 +92,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
|
||||||
() -> {
|
() -> {
|
||||||
// todo (6.0) : how to make sure things we need are ready to go?
|
// todo (6.0) : how to make sure things we need are ready to go?
|
||||||
// - e.g., here, we need access to the sub-attributes
|
// - e.g., here, we need access to the sub-attributes
|
||||||
final List<AttributeMapping> subAttributes = targetMappingType.getEmbeddableTypeDescriptor().getAttributeMappings();
|
if ( targetMappingType.getEmbeddableTypeDescriptor().getNumberOfAttributeMappings() == 0 ) {
|
||||||
if ( subAttributes.isEmpty() ) {
|
|
||||||
// todo (6.0) : ^^ for now, this is the only way we "know" that the embeddable has not been finalized yet
|
// todo (6.0) : ^^ for now, this is the only way we "know" that the embeddable has not been finalized yet
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for {@link jakarta.persistence.EmbeddedId}
|
* Support for {@link jakarta.persistence.EmbeddedId}
|
||||||
|
@ -115,6 +116,10 @@ public class EmbeddedIdentifierMappingImpl
|
||||||
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
return getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return getEmbeddableTypeDescriptor().getFetchable( position );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyAccess getPropertyAccess() {
|
public PropertyAccess getPropertyAccess() {
|
||||||
|
|
|
@ -65,6 +65,7 @@ import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.FetchOptions;
|
import org.hibernate.sql.results.graph.FetchOptions;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
|
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
|
||||||
import org.hibernate.sql.results.graph.entity.internal.EntityFetchJoinedImpl;
|
import org.hibernate.sql.results.graph.entity.internal.EntityFetchJoinedImpl;
|
||||||
|
@ -579,6 +580,11 @@ public class EntityCollectionPart
|
||||||
return entityMappingType.getNumberOfFetchables();
|
return entityMappingType.getNumberOfFetchables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return entityMappingType.getFetchable( position );
|
||||||
|
}
|
||||||
|
|
||||||
public String getMappedBy() {
|
public String getMappedBy() {
|
||||||
return collectionDescriptor.getMappedByProperty();
|
return collectionDescriptor.getMappedByProperty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
|
@ -179,15 +180,13 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
||||||
session.getSessionFactory()
|
session.getSessionFactory()
|
||||||
);
|
);
|
||||||
|
|
||||||
final List<AttributeMapping> virtualIdAttribute = virtualIdEmbeddable.getAttributeMappings();
|
final Object[] propertyValues = new Object[virtualIdEmbeddable.getNumberOfAttributeMappings()];
|
||||||
final List<AttributeMapping> idClassAttribute = getAttributeMappings();
|
|
||||||
final Object[] propertyValues = new Object[virtualIdAttribute.size()];
|
|
||||||
|
|
||||||
for ( int i = 0; i < propertyValues.length; i++ ) {
|
for ( int i = 0; i < propertyValues.length; i++ ) {
|
||||||
final AttributeMapping attributeMapping = virtualIdAttribute.get( i );
|
final AttributeMapping attributeMapping = virtualIdEmbeddable.getAttributeMapping( i );
|
||||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( entity );
|
final Object o = attributeMapping.getPropertyAccess().getGetter().get( entity );
|
||||||
if ( o == null ) {
|
if ( o == null ) {
|
||||||
final AttributeMapping idClassAttributeMapping = idClassAttribute.get( i );
|
final AttributeMapping idClassAttributeMapping = getAttributeMapping( i );
|
||||||
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
||||||
propertyValues[i] = idClassAttributeMapping.getExpressibleJavaType().getDefaultValue();
|
propertyValues[i] = idClassAttributeMapping.getExpressibleJavaType().getDefaultValue();
|
||||||
}
|
}
|
||||||
|
@ -197,7 +196,7 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
||||||
}
|
}
|
||||||
//JPA 2 @MapsId + @IdClass points to the pk of the entity
|
//JPA 2 @MapsId + @IdClass points to the pk of the entity
|
||||||
else if ( attributeMapping instanceof ToOneAttributeMapping
|
else if ( attributeMapping instanceof ToOneAttributeMapping
|
||||||
&& !( idClassAttribute.get( i ) instanceof ToOneAttributeMapping ) ) {
|
&& !( getAttributeMapping( i ) instanceof ToOneAttributeMapping ) ) {
|
||||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
||||||
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(
|
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(
|
||||||
toOneAttributeMapping.getSideNature().inverse()
|
toOneAttributeMapping.getSideNature().inverse()
|
||||||
|
@ -339,6 +338,11 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
||||||
return getNumberOfAttributeMappings();
|
return getNumberOfAttributeMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return attributeMappings.get( position );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityMappingType findContainingEntityMapping() {
|
public EntityMappingType findContainingEntityMapping() {
|
||||||
return idMapping.findContainingEntityMapping();
|
return idMapping.findContainingEntityMapping();
|
||||||
|
@ -415,12 +419,10 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||||
final List<AttributeMapping> attributeMappings = getAttributeMappings();
|
|
||||||
|
|
||||||
// todo (6.0) : reduce to-one values to id here?
|
// todo (6.0) : reduce to-one values to id here?
|
||||||
final Object[] result = new Object[ attributeMappings.size() ];
|
final Object[] result = new Object[ getNumberOfAttributeMappings() ];
|
||||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
for ( int i = 0; i < result.length; i++ ) {
|
||||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
final AttributeMapping attributeMapping = getAttributeMapping( i );
|
||||||
Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||||
result[i] = attributeMapping.disassemble( o, session );
|
result[i] = attributeMapping.disassemble( o, session );
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The inverse part of a "non-aggregated" composite identifier.
|
* The inverse part of a "non-aggregated" composite identifier.
|
||||||
|
@ -153,31 +154,31 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
|
||||||
navigablePath,
|
navigablePath,
|
||||||
getContainingTableExpression()
|
getContainingTableExpression()
|
||||||
);
|
);
|
||||||
int offset = 0;
|
identifierValueMapper.forEachSelectable(
|
||||||
for ( AttributeMapping attributeMapping : identifierValueMapper.getAttributeMappings() ) {
|
0,
|
||||||
offset += attributeMapping.forEachSelectable(
|
(columnIndex, selection) -> {
|
||||||
offset,
|
final TableReference tableReference = defaultTableReference.resolveTableReference( selection.getContainingTableExpression() ) != null
|
||||||
(columnIndex, selection) -> {
|
? defaultTableReference
|
||||||
final TableReference tableReference = defaultTableReference.resolveTableReference( selection.getContainingTableExpression() ) != null
|
: tableGroup.resolveTableReference(
|
||||||
? defaultTableReference
|
navigablePath,
|
||||||
: tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
|
selection.getContainingTableExpression()
|
||||||
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
|
);
|
||||||
.resolveSqlExpression(
|
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
|
||||||
SqlExpressionResolver.createColumnReferenceKey(
|
.resolveSqlExpression(
|
||||||
tableReference,
|
SqlExpressionResolver.createColumnReferenceKey(
|
||||||
selection.getSelectionExpression()
|
tableReference,
|
||||||
),
|
selection.getSelectionExpression()
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
),
|
||||||
tableReference.getIdentificationVariable(),
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
selection,
|
tableReference.getIdentificationVariable(),
|
||||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
selection,
|
||||||
)
|
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
columnReferences.add( (ColumnReference) columnReference );
|
columnReferences.add( (ColumnReference) columnReference );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return new SqlTuple( columnReferences, this );
|
return new SqlTuple( columnReferences, this );
|
||||||
}
|
}
|
||||||
|
@ -196,14 +197,13 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
|
||||||
null,
|
null,
|
||||||
null//sessionFactory
|
null//sessionFactory
|
||||||
);
|
);
|
||||||
final List<AttributeMapping> attributeMappings = getEmbeddableTypeDescriptor().getAttributeMappings();
|
final EmbeddableMappingType embeddableTypeDescriptor = getEmbeddableTypeDescriptor();
|
||||||
final List<AttributeMapping> idClassAttributeMappings = identifierValueMapper.getAttributeMappings();
|
final Object[] propertyValues = new Object[embeddableTypeDescriptor.getNumberOfAttributeMappings()];
|
||||||
final Object[] propertyValues = new Object[attributeMappings.size()];
|
|
||||||
for ( int i = 0; i < propertyValues.length; i++ ) {
|
for ( int i = 0; i < propertyValues.length; i++ ) {
|
||||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
||||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( entity );
|
final Object o = attributeMapping.getPropertyAccess().getGetter().get( entity );
|
||||||
if ( o == null ) {
|
if ( o == null ) {
|
||||||
final AttributeMapping idClassAttributeMapping = idClassAttributeMappings.get( i );
|
final AttributeMapping idClassAttributeMapping = identifierValueMapper.getAttributeMapping( i );
|
||||||
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
||||||
propertyValues[i] = idClassAttributeMapping.getExpressibleJavaType().getDefaultValue();
|
propertyValues[i] = idClassAttributeMapping.getExpressibleJavaType().getDefaultValue();
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
|
||||||
}
|
}
|
||||||
//JPA 2 @MapsId + @IdClass points to the pk of the entity
|
//JPA 2 @MapsId + @IdClass points to the pk of the entity
|
||||||
else if ( attributeMapping instanceof ToOneAttributeMapping
|
else if ( attributeMapping instanceof ToOneAttributeMapping
|
||||||
&& !( idClassAttributeMappings.get( i ) instanceof ToOneAttributeMapping ) ) {
|
&& !( identifierValueMapper.getAttributeMapping( i ) instanceof ToOneAttributeMapping ) ) {
|
||||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
||||||
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(
|
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(
|
||||||
toOneAttributeMapping.getSideNature().inverse()
|
toOneAttributeMapping.getSideNature().inverse()
|
||||||
|
@ -240,39 +240,35 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
|
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
|
||||||
final List<AttributeMapping> mappedIdAttributeMappings = identifierValueMapper.getAttributeMappings();
|
final Object[] propertyValues = new Object[identifierValueMapper.getNumberOfAttributeMappings()];
|
||||||
final Object[] propertyValues = new Object[mappedIdAttributeMappings.size()];
|
final EmbeddableMappingType embeddableTypeDescriptor = getEmbeddableTypeDescriptor();
|
||||||
|
for ( int position = 0; position < propertyValues.length; position++ ) {
|
||||||
getEmbeddableTypeDescriptor().forEachAttributeMapping(
|
final AttributeMapping attribute = embeddableTypeDescriptor.getAttributeMapping( position );
|
||||||
(position, attribute) -> {
|
final AttributeMapping mappedIdAttributeMapping = identifierValueMapper.getAttributeMapping( position );
|
||||||
final AttributeMapping mappedIdAttributeMapping = mappedIdAttributeMappings.get( position );
|
Object o = mappedIdAttributeMapping.getPropertyAccess().getGetter().get( id );
|
||||||
final Object o = mappedIdAttributeMapping.getPropertyAccess().getGetter().get( id );
|
if ( attribute instanceof ToOneAttributeMapping && !( mappedIdAttributeMapping instanceof ToOneAttributeMapping ) ) {
|
||||||
if ( attribute instanceof ToOneAttributeMapping && !( mappedIdAttributeMapping instanceof ToOneAttributeMapping ) ) {
|
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attribute;
|
||||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attribute;
|
final EntityPersister entityPersister = toOneAttributeMapping.getEntityMappingType()
|
||||||
final EntityPersister entityPersister = toOneAttributeMapping.getEntityMappingType()
|
.getEntityPersister();
|
||||||
.getEntityPersister();
|
final EntityKey entityKey = session.generateEntityKey( o, entityPersister );
|
||||||
final EntityKey entityKey = session.generateEntityKey( o, entityPersister );
|
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
// it is conceivable there is a proxy, so check that first
|
||||||
// it is conceivable there is a proxy, so check that first
|
o = persistenceContext.getProxy( entityKey );
|
||||||
propertyValues[position] = persistenceContext.getProxy( entityKey );
|
if ( o == null ) {
|
||||||
if ( propertyValues[position] == null ) {
|
// otherwise look for an initialized version
|
||||||
// otherwise look for an initialized version
|
o = persistenceContext.getEntity( entityKey );
|
||||||
propertyValues[position] = persistenceContext.getEntity( entityKey );
|
if ( o == null ) {
|
||||||
if ( propertyValues[position] == null ) {
|
o = entityDescriptor
|
||||||
propertyValues[position] = entityDescriptor
|
.findAttributeMapping( toOneAttributeMapping.getAttributeName() )
|
||||||
.findAttributeMapping( toOneAttributeMapping.getAttributeName() )
|
.getPropertyAccess()
|
||||||
.getPropertyAccess()
|
.getGetter()
|
||||||
.getGetter()
|
.get( entity );
|
||||||
.get( entity );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
propertyValues[position] = o;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
getEmbeddableTypeDescriptor().setValues( entity, propertyValues );
|
propertyValues[position] = o;
|
||||||
|
}
|
||||||
|
embeddableTypeDescriptor.setValues( entity, propertyValues );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -313,6 +309,11 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNumberOfFetchables() {
|
public int getNumberOfFetchables() {
|
||||||
return identifierValueMapper.getNumberOfFetchables();
|
return getPartMappingType().getNumberOfFetchables();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return getPartMappingType().getFetchable( position );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A "non-aggregated" composite identifier.
|
* A "non-aggregated" composite identifier.
|
||||||
|
@ -179,31 +180,31 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
||||||
navigablePath,
|
navigablePath,
|
||||||
getContainingTableExpression()
|
getContainingTableExpression()
|
||||||
);
|
);
|
||||||
int offset = 0;
|
identifierValueMapper.forEachSelectable(
|
||||||
for ( AttributeMapping attributeMapping : identifierValueMapper.getAttributeMappings() ) {
|
0,
|
||||||
offset += attributeMapping.forEachSelectable(
|
(columnIndex, selection) -> {
|
||||||
offset,
|
final TableReference tableReference = defaultTableReference.resolveTableReference( selection.getContainingTableExpression() ) != null
|
||||||
(columnIndex, selection) -> {
|
? defaultTableReference
|
||||||
final TableReference tableReference = defaultTableReference.resolveTableReference( selection.getContainingTableExpression() ) != null
|
: tableGroup.resolveTableReference(
|
||||||
? defaultTableReference
|
navigablePath,
|
||||||
: tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
|
selection.getContainingTableExpression()
|
||||||
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
|
);
|
||||||
.resolveSqlExpression(
|
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
|
||||||
SqlExpressionResolver.createColumnReferenceKey(
|
.resolveSqlExpression(
|
||||||
tableReference,
|
SqlExpressionResolver.createColumnReferenceKey(
|
||||||
selection.getSelectionExpression()
|
tableReference,
|
||||||
),
|
selection.getSelectionExpression()
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
),
|
||||||
tableReference.getIdentificationVariable(),
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
selection,
|
tableReference.getIdentificationVariable(),
|
||||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
selection,
|
||||||
)
|
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
columnReferences.add( (ColumnReference) columnReference );
|
columnReferences.add( (ColumnReference) columnReference );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return new SqlTuple( columnReferences, this );
|
return new SqlTuple( columnReferences, this );
|
||||||
}
|
}
|
||||||
|
@ -222,14 +223,13 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
||||||
null,
|
null,
|
||||||
sessionFactory
|
sessionFactory
|
||||||
);
|
);
|
||||||
final List<AttributeMapping> attributeMappings = getEmbeddableTypeDescriptor().getAttributeMappings();
|
final EmbeddableMappingType embeddableTypeDescriptor = getEmbeddableTypeDescriptor();
|
||||||
final List<AttributeMapping> idClassAttributeMappings = identifierValueMapper.getAttributeMappings();
|
final Object[] propertyValues = new Object[embeddableTypeDescriptor.getNumberOfAttributeMappings()];
|
||||||
final Object[] propertyValues = new Object[attributeMappings.size()];
|
|
||||||
for ( int i = 0; i < propertyValues.length; i++ ) {
|
for ( int i = 0; i < propertyValues.length; i++ ) {
|
||||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
||||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( entity );
|
final Object o = attributeMapping.getPropertyAccess().getGetter().get( entity );
|
||||||
if ( o == null ) {
|
if ( o == null ) {
|
||||||
final AttributeMapping idClassAttributeMapping = idClassAttributeMappings.get( i );
|
final AttributeMapping idClassAttributeMapping = identifierValueMapper.getAttributeMapping( i );
|
||||||
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
||||||
propertyValues[i] = idClassAttributeMapping.getExpressibleJavaType().getDefaultValue();
|
propertyValues[i] = idClassAttributeMapping.getExpressibleJavaType().getDefaultValue();
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
||||||
}
|
}
|
||||||
//JPA 2 @MapsId + @IdClass points to the pk of the entity
|
//JPA 2 @MapsId + @IdClass points to the pk of the entity
|
||||||
else if ( attributeMapping instanceof ToOneAttributeMapping
|
else if ( attributeMapping instanceof ToOneAttributeMapping
|
||||||
&& !( idClassAttributeMappings.get( i ) instanceof ToOneAttributeMapping ) ) {
|
&& !( identifierValueMapper.getAttributeMapping( i ) instanceof ToOneAttributeMapping ) ) {
|
||||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
||||||
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(
|
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(
|
||||||
toOneAttributeMapping.getSideNature().inverse()
|
toOneAttributeMapping.getSideNature().inverse()
|
||||||
|
@ -266,39 +266,35 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
|
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
|
||||||
final List<AttributeMapping> mappedIdAttributeMappings = identifierValueMapper.getAttributeMappings();
|
final Object[] propertyValues = new Object[identifierValueMapper.getNumberOfAttributeMappings()];
|
||||||
final Object[] propertyValues = new Object[mappedIdAttributeMappings.size()];
|
final EmbeddableMappingType embeddableTypeDescriptor = getEmbeddableTypeDescriptor();
|
||||||
|
for ( int i = 0; i < propertyValues.length; i++ ) {
|
||||||
getEmbeddableTypeDescriptor().forEachAttributeMapping(
|
final AttributeMapping attribute = embeddableTypeDescriptor.getAttributeMapping( i );
|
||||||
(position, attribute) -> {
|
final AttributeMapping mappedIdAttributeMapping = identifierValueMapper.getAttributeMapping( i );
|
||||||
final AttributeMapping mappedIdAttributeMapping = mappedIdAttributeMappings.get( position );
|
Object o = mappedIdAttributeMapping.getPropertyAccess().getGetter().get( id );
|
||||||
final Object o = mappedIdAttributeMapping.getPropertyAccess().getGetter().get( id );
|
if ( attribute instanceof ToOneAttributeMapping && !( mappedIdAttributeMapping instanceof ToOneAttributeMapping ) ) {
|
||||||
if ( attribute instanceof ToOneAttributeMapping && !( mappedIdAttributeMapping instanceof ToOneAttributeMapping ) ) {
|
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attribute;
|
||||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attribute;
|
final EntityPersister entityPersister = toOneAttributeMapping.getEntityMappingType()
|
||||||
final EntityPersister entityPersister = toOneAttributeMapping.getEntityMappingType()
|
.getEntityPersister();
|
||||||
.getEntityPersister();
|
final EntityKey entityKey = session.generateEntityKey( o, entityPersister );
|
||||||
final EntityKey entityKey = session.generateEntityKey( o, entityPersister );
|
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
// it is conceivable there is a proxy, so check that first
|
||||||
// it is conceivable there is a proxy, so check that first
|
o = persistenceContext.getProxy( entityKey );
|
||||||
propertyValues[position] = persistenceContext.getProxy( entityKey );
|
if ( o == null ) {
|
||||||
if ( propertyValues[position] == null ) {
|
// otherwise look for an initialized version
|
||||||
// otherwise look for an initialized version
|
o = persistenceContext.getEntity( entityKey );
|
||||||
propertyValues[position] = persistenceContext.getEntity( entityKey );
|
if ( o == null ) {
|
||||||
if ( propertyValues[position] == null ) {
|
// get the association out of the entity itself
|
||||||
// get the association out of the entity itself
|
o = entityDescriptor.getPropertyValue(
|
||||||
propertyValues[position] = entityDescriptor.getPropertyValue(
|
entity,
|
||||||
entity,
|
toOneAttributeMapping.getAttributeName()
|
||||||
toOneAttributeMapping.getAttributeName()
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
propertyValues[position] = o;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
getEmbeddableTypeDescriptor().setValues( entity, propertyValues );
|
propertyValues[i] = o;
|
||||||
|
}
|
||||||
|
embeddableTypeDescriptor.setValues( entity, propertyValues );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -339,6 +335,11 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNumberOfFetchables() {
|
public int getNumberOfFetchables() {
|
||||||
return identifierValueMapper.getNumberOfFetchables();
|
return getPartMappingType().getNumberOfFetchables();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return getPartMappingType().getFetchable( position );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -926,11 +926,6 @@ public class PluralAttributeMappingImpl
|
||||||
return elementDescriptor.forEachDisassembledJdbcValue( value, clause, offset, valuesConsumer, session );
|
return elementDescriptor.forEachDisassembledJdbcValue( value, clause, offset, valuesConsumer, session );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getNumberOfFetchables() {
|
|
||||||
return indexDescriptor == null ? 1 : 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "PluralAttribute(" + getCollectionDescriptor().getRole() + ")";
|
return "PluralAttribute(" + getCollectionDescriptor().getRole() + ")";
|
||||||
|
|
|
@ -82,6 +82,7 @@ import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchOptions;
|
import org.hibernate.sql.results.graph.FetchOptions;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
import org.hibernate.sql.results.graph.entity.EntityFetch;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
|
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
|
||||||
|
@ -1546,6 +1547,11 @@ public class ToOneAttributeMapping
|
||||||
return getEntityMappingType().getNumberOfFetchables();
|
return getEntityMappingType().getNumberOfFetchables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return getEntityMappingType().getFetchable( position );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableGroupJoin createTableGroupJoin(
|
public TableGroupJoin createTableGroupJoin(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
|
@ -257,6 +258,11 @@ public class VirtualIdEmbeddable extends AbstractEmbeddableMapping implements Id
|
||||||
return getNumberOfAttributeMappings();
|
return getNumberOfAttributeMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return attributeMappings.get( position );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityMappingType findContainingEntityMapping() {
|
public EntityMappingType findContainingEntityMapping() {
|
||||||
return idMapping.findContainingEntityMapping();
|
return idMapping.findContainingEntityMapping();
|
||||||
|
|
|
@ -247,6 +247,7 @@ import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
import org.hibernate.sql.results.graph.Fetchable;
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
|
import org.hibernate.sql.results.graph.FetchableContainer;
|
||||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
|
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
|
||||||
import org.hibernate.sql.results.graph.entity.internal.EntityResultImpl;
|
import org.hibernate.sql.results.graph.entity.internal.EntityResultImpl;
|
||||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||||
|
@ -1970,55 +1971,56 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Fetch> fetchProcessor(FetchParent fetchParent, QuerySpec querySpec, LoaderSqlAstCreationState creationState) {
|
private List<Fetch> fetchProcessor(FetchParent fetchParent, QuerySpec querySpec, LoaderSqlAstCreationState creationState) {
|
||||||
final List<Fetch> fetches = new ArrayList<>();
|
final FetchableContainer fetchableContainer = fetchParent.getReferencedMappingContainer();
|
||||||
final String rootTableName = getRootTableName();
|
final int size = fetchableContainer.getNumberOfFetchables();
|
||||||
fetchParent.getReferencedMappingContainer().visitFetchables(
|
final List<Fetch> fetches = new ArrayList<>( size );
|
||||||
fetchable -> {
|
|
||||||
// Ignore plural attributes
|
|
||||||
if ( !(fetchable instanceof PluralAttributeMapping ) ) {
|
|
||||||
final FetchTiming fetchTiming;
|
|
||||||
if ( fetchable instanceof BasicValuedModelPart ) {
|
|
||||||
// Ignore lazy basic columns
|
|
||||||
fetchTiming = fetchable.getMappedFetchOptions().getTiming();
|
|
||||||
if ( fetchTiming == FetchTiming.DELAYED ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( fetchable instanceof Association ) {
|
|
||||||
final Association association = (Association) fetchable;
|
|
||||||
// Ignore the fetchable if the FK is on the other side
|
|
||||||
if ( association.getSideNature() == ForeignKeyDescriptor.Nature.TARGET ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Ensure the FK comes from the root table
|
|
||||||
if ( !rootTableName.equals( association.getForeignKeyDescriptor().getKeyTable() ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fetchTiming = FetchTiming.DELAYED;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fetchTiming = fetchable.getMappedFetchOptions().getTiming();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( fetchTiming == null ) {
|
for ( int i = 0; i < size; i++ ) {
|
||||||
throw new AssertionFailure("fetchTiming was null");
|
final Fetchable fetchable = fetchableContainer.getFetchable( i );
|
||||||
}
|
// Ignore plural attributes
|
||||||
|
if ( !( fetchable instanceof PluralAttributeMapping ) ) {
|
||||||
if ( isSelectable( fetchParent, fetchable ) ) {
|
final FetchTiming fetchTiming;
|
||||||
final Fetch fetch = fetchParent.generateFetchableFetch(
|
if ( fetchable instanceof BasicValuedModelPart ) {
|
||||||
fetchable,
|
// Ignore lazy basic columns
|
||||||
fetchParent.resolveNavigablePath( fetchable ),
|
fetchTiming = fetchable.getMappedFetchOptions().getTiming();
|
||||||
fetchTiming,
|
if ( fetchTiming == FetchTiming.DELAYED ) {
|
||||||
true,
|
continue;
|
||||||
null,
|
|
||||||
creationState
|
|
||||||
);
|
|
||||||
fetches.add( fetch );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
null
|
else if ( fetchable instanceof Association ) {
|
||||||
);
|
final Association association = (Association) fetchable;
|
||||||
|
// Ignore the fetchable if the FK is on the other side
|
||||||
|
if ( association.getSideNature() == ForeignKeyDescriptor.Nature.TARGET ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Ensure the FK comes from the root table
|
||||||
|
if ( !getRootTableName().equals( association.getForeignKeyDescriptor().getKeyTable() ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fetchTiming = FetchTiming.DELAYED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fetchTiming = fetchable.getMappedFetchOptions().getTiming();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( fetchTiming == null ) {
|
||||||
|
throw new AssertionFailure("fetchTiming was null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isSelectable( fetchParent, fetchable ) ) {
|
||||||
|
final Fetch fetch = fetchParent.generateFetchableFetch(
|
||||||
|
fetchable,
|
||||||
|
fetchParent.resolveNavigablePath( fetchable ),
|
||||||
|
fetchTiming,
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
creationState
|
||||||
|
);
|
||||||
|
fetches.add( fetch );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return fetches;
|
return fetches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5084,31 +5086,23 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( hasSubclasses() ) {
|
if ( hasSubclasses() ) {
|
||||||
visitAttributeMappings(
|
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||||
attribute -> {
|
final Object value = values[i];
|
||||||
final int stateArrayPosition = attribute.getStateArrayPosition();
|
if ( value != UNFETCHED_PROPERTY ) {
|
||||||
final Object value = values[stateArrayPosition];
|
final Setter setter = attributeMappings.get( i ).getPropertyAccess().getSetter();
|
||||||
if ( value != UNFETCHED_PROPERTY ) {
|
setter.set( object, value );
|
||||||
final Setter setter = attribute.getPropertyAccess().getSetter();
|
}
|
||||||
setter.set( object, value );
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
visitFetchables(
|
for ( int i = 0; i < staticFetchableList.size(); i++ ) {
|
||||||
fetchable -> {
|
final AttributeMapping attribute = (AttributeMapping) staticFetchableList.get( i );
|
||||||
final AttributeMapping attribute = (AttributeMapping) fetchable;
|
final Object value = values[i];
|
||||||
final int stateArrayPosition = attribute.getStateArrayPosition();
|
if ( value != UNFETCHED_PROPERTY ) {
|
||||||
final Object value = values[stateArrayPosition];
|
final Setter setter = attribute.getPropertyAccess().getSetter();
|
||||||
if ( value != UNFETCHED_PROPERTY ) {
|
setter.set( object, value );
|
||||||
final Setter setter = attribute.getPropertyAccess().getSetter();
|
}
|
||||||
setter.set( object, value );
|
}
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6101,7 +6095,7 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitDeclaredAttributeMappings(Consumer<? super AttributeMapping> action) {
|
public void visitDeclaredAttributeMappings(Consumer<? super AttributeMapping> action) {
|
||||||
declaredAttributeMappings.forEach( (key,value) -> action.accept( value ) );
|
declaredAttributeMappings.values().forEach( action );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6700,22 +6694,33 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitKeyFetchables(
|
public void visitKeyFetchables(Consumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
Consumer<Fetchable> fetchableConsumer,
|
// No-op
|
||||||
EntityMappingType treatTargetType) {
|
}
|
||||||
// final EntityIdentifierMapping identifierMapping = getIdentifierMapping();
|
|
||||||
// if ( identifierMapping instanceof FetchableContainer ) {
|
@Override
|
||||||
// // essentially means the entity has a composite id - ask the embeddable to visit its fetchables
|
public void visitKeyFetchables(IndexedConsumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
// ( (FetchableContainer) identifierMapping ).visitFetchables( fetchableConsumer, treatTargetType );
|
// No-op
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// fetchableConsumer.accept( (Fetchable) identifierMapping );
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNumberOfFetchables() {
|
public int getNumberOfFetchables() {
|
||||||
return attributeMappings.size();
|
return getStaticFetchableList().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfKeyFetchables() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getKeyFetchable(int position) {
|
||||||
|
throw new IndexOutOfBoundsException( position );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fetchable getFetchable(int position) {
|
||||||
|
return getStaticFetchableList().get( position );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6737,6 +6742,35 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitFetchables(IndexedConsumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
|
||||||
|
if ( treatTargetType == null ) {
|
||||||
|
final List<Fetchable> fetchableList = getStaticFetchableList();
|
||||||
|
final int size = fetchableList.size();
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
fetchableConsumer.accept( i, fetchableList.get( i ) );
|
||||||
|
}
|
||||||
|
// EARLY EXIT!!!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int size = attributeMappings.size();
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
fetchableConsumer.accept( i, attributeMappings.get( i ) );
|
||||||
|
}
|
||||||
|
if ( treatTargetType.isTypeOrSuperType( this ) ) {
|
||||||
|
if ( subclassMappingTypes != null ) {
|
||||||
|
int offset = size;
|
||||||
|
for ( EntityMappingType subtype : subclassMappingTypes.values() ) {
|
||||||
|
final Collection<AttributeMapping> declaredAttributeMappings = subtype.getDeclaredAttributeMappings();
|
||||||
|
for ( AttributeMapping declaredAttributeMapping : declaredAttributeMappings ) {
|
||||||
|
fetchableConsumer.accept( offset++, declaredAttributeMapping );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected List<Fetchable> getStaticFetchableList() {
|
protected List<Fetchable> getStaticFetchableList() {
|
||||||
return staticFetchableList;
|
return staticFetchableList;
|
||||||
}
|
}
|
||||||
|
@ -6769,7 +6803,9 @@ public abstract class AbstractEntityPersister
|
||||||
public void visitSubTypeAttributeMappings(Consumer<? super AttributeMapping> action) {
|
public void visitSubTypeAttributeMappings(Consumer<? super AttributeMapping> action) {
|
||||||
visitAttributeMappings( action );
|
visitAttributeMappings( action );
|
||||||
if ( subclassMappingTypes != null ) {
|
if ( subclassMappingTypes != null ) {
|
||||||
subclassMappingTypes.forEach( (s, subType) -> subType.visitDeclaredAttributeMappings( action ) );
|
for ( EntityMappingType subType : subclassMappingTypes.values() ) {
|
||||||
|
subType.visitDeclaredAttributeMappings( action );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -462,17 +462,16 @@ public interface EntityPersister
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
default void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
|
||||||
final List<AttributeMapping> attributeMappings = getAttributeMappings();
|
|
||||||
if ( domainValue instanceof Object[] ) {
|
if ( domainValue instanceof Object[] ) {
|
||||||
final Object[] values = (Object[]) domainValue;
|
final Object[] values = (Object[]) domainValue;
|
||||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
for ( int i = 0; i < getNumberOfAttributeMappings(); i++ ) {
|
||||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
final AttributeMapping attributeMapping = getAttributeMapping( i );
|
||||||
attributeMapping.breakDownJdbcValues( values[ i ], valueConsumer, session );
|
attributeMapping.breakDownJdbcValues( values[ i ], valueConsumer, session );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
for ( int i = 0; i < getNumberOfAttributeMappings(); i++ ) {
|
||||||
final AttributeMapping attributeMapping = attributeMappings.get( 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 );
|
attributeMapping.breakDownJdbcValues( attributeValue, valueConsumer, session );
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,26 +6,31 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.query.results.implicit;
|
package org.hibernate.query.results.implicit;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.spi.NavigablePath;
|
import org.hibernate.spi.NavigablePath;
|
||||||
import org.hibernate.query.results.Builders;
|
import org.hibernate.query.results.Builders;
|
||||||
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
import org.hibernate.query.results.DomainResultCreationStateImpl;
|
||||||
import org.hibernate.query.results.FetchBuilder;
|
import org.hibernate.query.results.FetchBuilder;
|
||||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
|
||||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||||
|
|
||||||
|
@ -48,24 +53,22 @@ public class ImplicitFetchBuilderEmbeddable implements ImplicitFetchBuilder {
|
||||||
final DomainResultCreationStateImpl creationStateImpl = impl( creationState );
|
final DomainResultCreationStateImpl creationStateImpl = impl( creationState );
|
||||||
final NavigablePath relativePath = creationStateImpl.getCurrentRelativePath();
|
final NavigablePath relativePath = creationStateImpl.getCurrentRelativePath();
|
||||||
final Function<String, FetchBuilder> fetchBuilderResolver = creationStateImpl.getCurrentExplicitFetchMementoResolver();
|
final Function<String, FetchBuilder> fetchBuilderResolver = creationStateImpl.getCurrentExplicitFetchMementoResolver();
|
||||||
final Map<NavigablePath, FetchBuilder> fetchBuilders = new LinkedHashMap<>( fetchable.getNumberOfFetchables() );
|
final int size = fetchable.getNumberOfFetchables();
|
||||||
fetchable.visitFetchables(
|
final Map<NavigablePath, FetchBuilder> fetchBuilders = CollectionHelper.linkedMapOfSize( size );
|
||||||
subFetchable -> {
|
for ( int i = 0; i < size; i++ ) {
|
||||||
final NavigablePath subFetchPath = relativePath.append( subFetchable.getFetchableName() );
|
final Fetchable subFetchable = fetchable.getFetchable( i );
|
||||||
final FetchBuilder explicitFetchBuilder = fetchBuilderResolver
|
final NavigablePath subFetchPath = relativePath.append( subFetchable.getFetchableName() );
|
||||||
.apply( subFetchPath.getFullPath() );
|
final FetchBuilder explicitFetchBuilder = fetchBuilderResolver.apply( subFetchPath.getFullPath() );
|
||||||
if ( explicitFetchBuilder == null ) {
|
if ( explicitFetchBuilder == null ) {
|
||||||
fetchBuilders.put(
|
fetchBuilders.put(
|
||||||
subFetchPath,
|
subFetchPath,
|
||||||
Builders.implicitFetchBuilder( fetchPath, subFetchable, creationStateImpl )
|
Builders.implicitFetchBuilder( fetchPath, subFetchable, creationStateImpl )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fetchBuilders.put( subFetchPath, explicitFetchBuilder );
|
fetchBuilders.put( subFetchPath, explicitFetchBuilder );
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
null
|
|
||||||
);
|
|
||||||
this.fetchBuilders = fetchBuilders;
|
this.fetchBuilders = fetchBuilders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||||
import org.hibernate.metamodel.mapping.MappingType;
|
import org.hibernate.metamodel.mapping.MappingType;
|
||||||
|
@ -27,6 +28,7 @@ import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||||
|
|
||||||
import static org.hibernate.query.results.ResultsHelper.impl;
|
import static org.hibernate.query.results.ResultsHelper.impl;
|
||||||
|
@ -70,24 +72,22 @@ public class ImplicitFetchBuilderEntity implements ImplicitFetchBuilder {
|
||||||
final MappingType partMappingType = foreignKeyDescriptor.getPartMappingType();
|
final MappingType partMappingType = foreignKeyDescriptor.getPartMappingType();
|
||||||
if ( partMappingType instanceof EmbeddableMappingType ) {
|
if ( partMappingType instanceof EmbeddableMappingType ) {
|
||||||
final EmbeddableMappingType embeddableValuedModelPart = (EmbeddableMappingType) partMappingType;
|
final EmbeddableMappingType embeddableValuedModelPart = (EmbeddableMappingType) partMappingType;
|
||||||
fetchBuilders = new LinkedHashMap<>( embeddableValuedModelPart.getNumberOfFetchables() );
|
final int size = embeddableValuedModelPart.getNumberOfFetchables();
|
||||||
embeddableValuedModelPart.visitFetchables(
|
fetchBuilders = CollectionHelper.linkedMapOfSize( size );
|
||||||
subFetchable -> {
|
for ( int i = 0; i < size; i++ ) {
|
||||||
final NavigablePath subFetchPath = associationKeyFetchPath.append( subFetchable.getFetchableName() );
|
final Fetchable subFetchable = embeddableValuedModelPart.getFetchable( i );
|
||||||
final FetchBuilder explicitFetchBuilder = fetchBuilderResolver
|
final NavigablePath subFetchPath = associationKeyFetchPath.append( subFetchable.getFetchableName() );
|
||||||
.apply( subFetchPath.getFullPath() );
|
final FetchBuilder explicitFetchBuilder = fetchBuilderResolver.apply( subFetchPath.getFullPath() );
|
||||||
if ( explicitFetchBuilder == null ) {
|
if ( explicitFetchBuilder == null ) {
|
||||||
fetchBuilders.put(
|
fetchBuilders.put(
|
||||||
subFetchPath,
|
subFetchPath,
|
||||||
Builders.implicitFetchBuilder( fetchPath, subFetchable, creationStateImpl )
|
Builders.implicitFetchBuilder( fetchPath, subFetchable, creationStateImpl )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fetchBuilders.put( subFetchPath, explicitFetchBuilder );
|
fetchBuilders.put( subFetchPath, explicitFetchBuilder );
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fetchBuilders = Collections.emptyMap();
|
fetchBuilders = Collections.emptyMap();
|
||||||
|
|
|
@ -374,6 +374,7 @@ import org.hibernate.sql.results.graph.EntityGraphTraversalState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchParent;
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
import org.hibernate.sql.results.graph.Fetchable;
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
|
import org.hibernate.sql.results.graph.FetchableContainer;
|
||||||
import org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiation;
|
import org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiation;
|
||||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||||
import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl;
|
import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl;
|
||||||
|
@ -5356,7 +5357,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for ( int i = 0; i < size; i++ ) {
|
for ( int i = 0; i < size; i++ ) {
|
||||||
final AttributeMapping attributeMapping = embeddableMappingType.getAttributeMappings().get( i );
|
final AttributeMapping attributeMapping = embeddableMappingType.getAttributeMapping( i );
|
||||||
inferrableTypeAccessStack.push( () -> attributeMapping );
|
inferrableTypeAccessStack.push( () -> attributeMapping );
|
||||||
try {
|
try {
|
||||||
expressions.add( (Expression) groupedExpressions.get( i ).accept( this ) );
|
expressions.add( (Expression) groupedExpressions.get( i ).accept( this ) );
|
||||||
|
@ -7092,10 +7093,16 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Fetch> visitFetches(FetchParent fetchParent) {
|
public List<Fetch> visitFetches(FetchParent fetchParent) {
|
||||||
final List<Fetch> fetches = CollectionHelper.arrayList( fetchParent.getReferencedMappingType().getNumberOfFetchables() );
|
final FetchableContainer referencedMappingContainer = fetchParent.getReferencedMappingContainer();
|
||||||
|
final int keySize = referencedMappingContainer.getNumberOfKeyFetchables();
|
||||||
fetchParent.getReferencedMappingContainer().visitKeyFetchables( fetchable -> addFetch( fetches, fetchParent, fetchable, true ), null );
|
final int size = referencedMappingContainer.getNumberOfFetchables();
|
||||||
fetchParent.getReferencedMappingContainer().visitFetchables( fetchable -> addFetch( fetches, fetchParent, fetchable, false ), null );
|
final List<Fetch> fetches = CollectionHelper.arrayList( keySize + size );
|
||||||
|
for ( int i = 0; i < keySize; i++ ) {
|
||||||
|
addFetch( fetches, fetchParent, referencedMappingContainer.getKeyFetchable( i ), true );
|
||||||
|
}
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
addFetch( fetches, fetchParent, referencedMappingContainer.getFetchable( i ), false );
|
||||||
|
}
|
||||||
return fetches;
|
return fetches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,12 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.sql.results.graph;
|
package org.hibernate.sql.results.graph;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.hibernate.internal.util.MutableInteger;
|
||||||
|
import org.hibernate.mapping.IndexedConsumer;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.ModelPartContainer;
|
import org.hibernate.metamodel.mapping.ModelPartContainer;
|
||||||
|
|
||||||
|
@ -17,21 +21,71 @@ import org.hibernate.metamodel.mapping.ModelPartContainer;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface FetchableContainer extends ModelPartContainer {
|
public interface FetchableContainer extends ModelPartContainer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of key fetchables in the container
|
||||||
|
*/
|
||||||
|
default int getNumberOfKeyFetchables() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of fetchables in the container
|
* The number of fetchables in the container
|
||||||
*/
|
*/
|
||||||
int getNumberOfFetchables();
|
int getNumberOfFetchables();
|
||||||
|
|
||||||
|
default Fetchable getKeyFetchable(int position) {
|
||||||
|
List<Fetchable> fetchables = new ArrayList<>( getNumberOfKeyFetchables() );
|
||||||
|
visitKeyFetchables( fetchable -> fetchables.add( fetchable ), null );
|
||||||
|
return fetchables.get( position );
|
||||||
|
}
|
||||||
|
|
||||||
|
default Fetchable getFetchable(int position) {
|
||||||
|
List<Fetchable> fetchables = new ArrayList<>( getNumberOfFetchables() );
|
||||||
|
visitFetchables( fetchable -> fetchables.add( fetchable ), null );
|
||||||
|
return fetchables.get( position );
|
||||||
|
}
|
||||||
|
|
||||||
default void visitKeyFetchables(
|
default void visitKeyFetchables(
|
||||||
Consumer<Fetchable> fetchableConsumer,
|
Consumer<Fetchable> fetchableConsumer,
|
||||||
EntityMappingType treatTargetType) {
|
EntityMappingType treatTargetType) {
|
||||||
// by default, nothing to do
|
// by default, nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void visitKeyFetchables(
|
||||||
|
IndexedConsumer<Fetchable> fetchableConsumer,
|
||||||
|
EntityMappingType treatTargetType) {
|
||||||
|
visitKeyFetchables( 0, fetchableConsumer, treatTargetType );
|
||||||
|
}
|
||||||
|
|
||||||
|
default void visitKeyFetchables(
|
||||||
|
int offset,
|
||||||
|
IndexedConsumer<Fetchable> fetchableConsumer,
|
||||||
|
EntityMappingType treatTargetType) {
|
||||||
|
// by default, nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
default void visitFetchables(
|
default void visitFetchables(
|
||||||
Consumer<Fetchable> fetchableConsumer,
|
Consumer<Fetchable> fetchableConsumer,
|
||||||
EntityMappingType treatTargetType) {
|
EntityMappingType treatTargetType) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
visitSubParts( (Consumer) fetchableConsumer, treatTargetType );
|
visitSubParts( (Consumer) fetchableConsumer, treatTargetType );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void visitFetchables(
|
||||||
|
IndexedConsumer<Fetchable> fetchableConsumer,
|
||||||
|
EntityMappingType treatTargetType) {
|
||||||
|
visitFetchables( 0, fetchableConsumer, treatTargetType );
|
||||||
|
}
|
||||||
|
|
||||||
|
default void visitFetchables(
|
||||||
|
int offset,
|
||||||
|
IndexedConsumer<Fetchable> fetchableConsumer,
|
||||||
|
EntityMappingType treatTargetType) {
|
||||||
|
final MutableInteger index = new MutableInteger( offset );
|
||||||
|
visitSubParts(
|
||||||
|
modelPart -> fetchableConsumer.accept( index.getAndIncrement(), (Fetchable) modelPart ),
|
||||||
|
treatTargetType
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||||
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.sql.results.graph.Initializer;
|
import org.hibernate.sql.results.graph.Initializer;
|
||||||
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
|
||||||
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
import org.hibernate.sql.results.graph.entity.EntityInitializer;
|
||||||
|
@ -90,22 +91,19 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
||||||
this.representationStrategy = representationEmbeddable.getRepresentationStrategy();
|
this.representationStrategy = representationEmbeddable.getRepresentationStrategy();
|
||||||
this.usesStandardInstantiation = representationStrategy.getInstantiator() instanceof StandardEmbeddableInstantiator;
|
this.usesStandardInstantiation = representationStrategy.getInstantiator() instanceof StandardEmbeddableInstantiator;
|
||||||
|
|
||||||
final int numOfAttrs = embeddableTypeDescriptor.getNumberOfAttributeMappings();
|
final int size = embeddableTypeDescriptor.getNumberOfFetchables();
|
||||||
this.rowState = new Object[ numOfAttrs ];
|
this.rowState = new Object[ size ];
|
||||||
this.assemblers = arrayList( numOfAttrs );
|
this.assemblers = arrayList( size );
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
final Fetchable stateArrayContributor = embeddableTypeDescriptor.getFetchable( i );
|
||||||
|
final Fetch fetch = resultDescriptor.findFetch( stateArrayContributor );
|
||||||
|
|
||||||
embeddableTypeDescriptor.visitFetchables(
|
final DomainResultAssembler<?> stateAssembler = fetch == null
|
||||||
stateArrayContributor -> {
|
? new NullValueAssembler<>( stateArrayContributor.getJavaType() )
|
||||||
final Fetch fetch = resultDescriptor.findFetch( stateArrayContributor );
|
: fetch.createAssembler( this, creationState );
|
||||||
|
|
||||||
final DomainResultAssembler<?> stateAssembler = fetch == null
|
assemblers.add( stateAssembler );
|
||||||
? new NullValueAssembler<>( stateArrayContributor.getJavaType() )
|
}
|
||||||
: fetch.createAssembler( this, creationState );
|
|
||||||
|
|
||||||
assemblers.add( stateAssembler );
|
|
||||||
},
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
// We never want to create empty composites for the FK target or PK, otherwise collections would break
|
// We never want to create empty composites for the FK target or PK, otherwise collections would break
|
||||||
createEmptyCompositesEnabled = !ForeignKeyDescriptor.PART_NAME.equals( navigablePath.getLocalName() )
|
createEmptyCompositesEnabled = !ForeignKeyDescriptor.PART_NAME.equals( navigablePath.getLocalName() )
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.event.spi.PreLoadEvent;
|
||||||
import org.hibernate.event.spi.PreLoadEventListener;
|
import org.hibernate.event.spi.PreLoadEventListener;
|
||||||
import org.hibernate.internal.util.NullnessHelper;
|
import org.hibernate.internal.util.NullnessHelper;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.loader.entity.CacheEntityLoaderHelper;
|
import org.hibernate.loader.entity.CacheEntityLoaderHelper;
|
||||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||||
|
@ -165,32 +166,29 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
this.rowIdAssembler = null;
|
this.rowIdAssembler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
assemblerMap = new IdentityHashMap<>( entityDescriptor.getNumberOfAttributeMappings() );
|
final int size = entityDescriptor.getNumberOfFetchables();
|
||||||
|
assemblerMap = new IdentityHashMap<>( CollectionHelper.determineProperSizing( size ) );
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
final AttributeMapping attributeMapping = (AttributeMapping) entityDescriptor.getFetchable( i );
|
||||||
|
|
||||||
entityDescriptor.visitFetchables(
|
// todo (6.0) : somehow we need to track whether all state is loaded/resolved
|
||||||
fetchable -> {
|
// note that lazy proxies or uninitialized collections count against
|
||||||
final AttributeMapping attributeMapping = (AttributeMapping) fetchable;
|
// that in the affirmative
|
||||||
|
|
||||||
// todo (6.0) : somehow we need to track whether all state is loaded/resolved
|
final Fetch fetch = resultDescriptor.findFetch( attributeMapping );
|
||||||
// note that lazy proxies or uninitialized collections count against
|
|
||||||
// that in the affirmative
|
|
||||||
|
|
||||||
final Fetch fetch = resultDescriptor.findFetch( fetchable );
|
final DomainResultAssembler<?> stateAssembler;
|
||||||
|
if ( fetch == null ) {
|
||||||
|
stateAssembler = new NullValueAssembler<>(
|
||||||
|
attributeMapping.getMappedType().getMappedJavaType()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stateAssembler = fetch.createAssembler( this, creationState );
|
||||||
|
}
|
||||||
|
|
||||||
final DomainResultAssembler<?> stateAssembler;
|
assemblerMap.put( attributeMapping, stateAssembler );
|
||||||
if ( fetch == null ) {
|
}
|
||||||
stateAssembler = new NullValueAssembler<>(
|
|
||||||
attributeMapping.getMappedType().getMappedJavaType()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
stateAssembler = fetch.createAssembler( this, creationState );
|
|
||||||
}
|
|
||||||
|
|
||||||
assemblerMap.put( attributeMapping, stateAssembler );
|
|
||||||
},
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void deepCopy(
|
private static void deepCopy(
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class EmbeddedComponentType extends ComponentType {
|
||||||
}
|
}
|
||||||
|
|
||||||
final EmbeddableMappingType embeddable = mappingModelPart().getEmbeddableTypeDescriptor();
|
final EmbeddableMappingType embeddable = mappingModelPart().getEmbeddableTypeDescriptor();
|
||||||
for ( int i = 0; i < embeddable.getAttributeMappings().size(); i++ ) {
|
for ( int i = 0; i < embeddable.getNumberOfAttributeMappings(); i++ ) {
|
||||||
final AttributeMapping attributeMapping = embeddable.getAttributeMapping( i );
|
final AttributeMapping attributeMapping = embeddable.getAttributeMapping( i );
|
||||||
final Getter getter = attributeMapping.getPropertyAccess().getGetter();
|
final Getter getter = attributeMapping.getPropertyAccess().getGetter();
|
||||||
final Method getterMethod = getter.getMethod();
|
final Method getterMethod = getter.getMethod();
|
||||||
|
|
Loading…
Reference in New Issue