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