HHH-18410 Make use of getter/setter cache as much as possible
This commit is contained in:
parent
7ef269100b
commit
73af6a0b75
|
@ -180,14 +180,14 @@ public abstract class AbstractEntityInsertAction extends EntityAction {
|
||||||
if ( attribute.isPluralAttributeMapping() ) {
|
if ( attribute.isPluralAttributeMapping() ) {
|
||||||
addCollectionKey(
|
addCollectionKey(
|
||||||
attribute.asPluralAttributeMapping(),
|
attribute.asPluralAttributeMapping(),
|
||||||
attribute.getPropertyAccess().getGetter().get( object ),
|
attribute.getValue( object ),
|
||||||
persistenceContext
|
persistenceContext
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if ( attribute.isEmbeddedAttributeMapping() ) {
|
else if ( attribute.isEmbeddedAttributeMapping() ) {
|
||||||
visitEmbeddedAttributeMapping(
|
visitEmbeddedAttributeMapping(
|
||||||
attribute.asEmbeddedAttributeMapping(),
|
attribute.asEmbeddedAttributeMapping(),
|
||||||
attribute.getPropertyAccess().getGetter().get( object ),
|
attribute.getValue( object ),
|
||||||
persistenceContext
|
persistenceContext
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,11 +86,17 @@ public final class Cascade {
|
||||||
LOG.tracev( "Processing cascade {0} for: {1}", action, persister.getEntityName() );
|
LOG.tracev( "Processing cascade {0} for: {1}", action, persister.getEntityName() );
|
||||||
}
|
}
|
||||||
final PersistenceContext persistenceContext = eventSource.getPersistenceContextInternal();
|
final PersistenceContext persistenceContext = eventSource.getPersistenceContextInternal();
|
||||||
final EntityEntry entry = persistenceContext.getEntry( parent );
|
final boolean enhancedForLazyLoading = persister.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
|
||||||
if ( entry != null && entry.getLoadedState() == null && entry.getStatus() == Status.MANAGED && persister.getBytecodeEnhancementMetadata()
|
final EntityEntry entry;
|
||||||
.isEnhancedForLazyLoading() ) {
|
if ( enhancedForLazyLoading ) {
|
||||||
|
entry = persistenceContext.getEntry( parent );
|
||||||
|
if ( entry != null && entry.getLoadedState() == null && entry.getStatus() == Status.MANAGED ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
entry = null;
|
||||||
|
}
|
||||||
final Type[] types = persister.getPropertyTypes();
|
final Type[] types = persister.getPropertyTypes();
|
||||||
final String[] propertyNames = persister.getPropertyNames();
|
final String[] propertyNames = persister.getPropertyNames();
|
||||||
final CascadeStyle[] cascadeStyles = persister.getPropertyCascadeStyles();
|
final CascadeStyle[] cascadeStyles = persister.getPropertyCascadeStyles();
|
||||||
|
@ -107,6 +113,7 @@ public final class Cascade {
|
||||||
if ( style.doCascade( action ) ) {
|
if ( style.doCascade( action ) ) {
|
||||||
final Object child;
|
final Object child;
|
||||||
if ( isUninitializedProperty ) {
|
if ( isUninitializedProperty ) {
|
||||||
|
assert enhancedForLazyLoading;
|
||||||
// parent is a bytecode enhanced entity.
|
// parent is a bytecode enhanced entity.
|
||||||
// Cascade to an uninitialized, lazy value only if
|
// Cascade to an uninitialized, lazy value only if
|
||||||
// parent is managed in the PersistenceContext.
|
// parent is managed in the PersistenceContext.
|
||||||
|
@ -378,7 +385,7 @@ public final class Cascade {
|
||||||
* @return True if the attribute represents a logical one to one association
|
* @return True if the attribute represents a logical one to one association
|
||||||
*/
|
*/
|
||||||
private static boolean isLogicalOneToOne(Type type) {
|
private static boolean isLogicalOneToOne(Type type) {
|
||||||
return type.isEntityType() && ( (EntityType) type ).isLogicalOneToOne();
|
return type instanceof EntityType && ( (EntityType) type ).isLogicalOneToOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean cascadeAssociationNow(final CascadePoint cascadePoint, AssociationType associationType) {
|
private static boolean cascadeAssociationNow(final CascadePoint cascadePoint, AssociationType associationType) {
|
||||||
|
|
|
@ -145,8 +145,7 @@ public final class Collections {
|
||||||
Object entity,
|
Object entity,
|
||||||
SessionImplementor session) {
|
SessionImplementor session) {
|
||||||
collection.setOwner( entity );
|
collection.setOwner( entity );
|
||||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
final CollectionEntry ce = session.getPersistenceContextInternal().getCollectionEntry( collection );
|
||||||
final CollectionEntry ce = persistenceContext.getCollectionEntry( collection );
|
|
||||||
|
|
||||||
if ( ce == null ) {
|
if ( ce == null ) {
|
||||||
// refer to comment in StatefulPersistenceContext.addCollection()
|
// refer to comment in StatefulPersistenceContext.addCollection()
|
||||||
|
|
|
@ -1316,7 +1316,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Map<PersistentCollection<?>,CollectionEntry> getCollectionEntries() {
|
public Map<PersistentCollection<?>,CollectionEntry> getCollectionEntries() {
|
||||||
return getOrInitializeCollectionEntries();
|
return collectionEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -521,11 +521,11 @@ public interface PersistenceContext {
|
||||||
JdbcValuesSourceProcessingState processingState,
|
JdbcValuesSourceProcessingState processingState,
|
||||||
EntityInitializer initializer);
|
EntityInitializer initializer);
|
||||||
|
|
||||||
EntityHolder getEntityHolder(EntityKey key);
|
@Nullable EntityHolder getEntityHolder(EntityKey key);
|
||||||
|
|
||||||
boolean containsEntityHolder(EntityKey key);
|
boolean containsEntityHolder(EntityKey key);
|
||||||
|
|
||||||
EntityHolder removeEntityHolder(EntityKey key);
|
@Nullable EntityHolder removeEntityHolder(EntityKey key);
|
||||||
|
|
||||||
@Incubating
|
@Incubating
|
||||||
void postLoad(JdbcValuesSourceProcessingState processingState, Consumer<EntityHolder> loadedConsumer);
|
void postLoad(JdbcValuesSourceProcessingState processingState, Consumer<EntityHolder> loadedConsumer);
|
||||||
|
@ -564,7 +564,7 @@ public interface PersistenceContext {
|
||||||
* Doubly internal
|
* Doubly internal
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
Map<PersistentCollection<?>,CollectionEntry> getCollectionEntries();
|
@Nullable Map<PersistentCollection<?>,CollectionEntry> getCollectionEntries();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute some action on each entry of the collectionEntries map, optionally iterating on a defensive copy.
|
* Execute some action on each entry of the collectionEntries map, optionally iterating on a defensive copy.
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.hibernate.action.internal.CollectionRecreateAction;
|
||||||
import org.hibernate.action.internal.CollectionRemoveAction;
|
import org.hibernate.action.internal.CollectionRemoveAction;
|
||||||
import org.hibernate.action.internal.CollectionUpdateAction;
|
import org.hibernate.action.internal.CollectionUpdateAction;
|
||||||
import org.hibernate.action.internal.QueuedOperationCollectionAction;
|
import org.hibernate.action.internal.QueuedOperationCollectionAction;
|
||||||
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.engine.internal.Cascade;
|
import org.hibernate.engine.internal.Cascade;
|
||||||
import org.hibernate.engine.internal.CascadePoint;
|
import org.hibernate.engine.internal.CascadePoint;
|
||||||
import org.hibernate.engine.internal.Collections;
|
import org.hibernate.engine.internal.Collections;
|
||||||
|
@ -21,6 +22,7 @@ import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||||
import org.hibernate.engine.spi.ActionQueue;
|
import org.hibernate.engine.spi.ActionQueue;
|
||||||
import org.hibernate.engine.spi.CascadingAction;
|
import org.hibernate.engine.spi.CascadingAction;
|
||||||
import org.hibernate.engine.spi.CascadingActions;
|
import org.hibernate.engine.spi.CascadingActions;
|
||||||
|
import org.hibernate.engine.spi.CollectionEntry;
|
||||||
import org.hibernate.engine.spi.CollectionKey;
|
import org.hibernate.engine.spi.CollectionKey;
|
||||||
import org.hibernate.engine.spi.EntityEntry;
|
import org.hibernate.engine.spi.EntityEntry;
|
||||||
import org.hibernate.engine.spi.PersistenceContext;
|
import org.hibernate.engine.spi.PersistenceContext;
|
||||||
|
@ -35,6 +37,7 @@ import org.hibernate.event.spi.FlushEvent;
|
||||||
import org.hibernate.event.spi.PersistContext;
|
import org.hibernate.event.spi.PersistContext;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.EntityPrinter;
|
import org.hibernate.internal.util.EntityPrinter;
|
||||||
|
import org.hibernate.internal.util.collections.IdentityMap;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
@ -183,7 +186,12 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
||||||
// and reset reached, doupdate, etc.
|
// and reset reached, doupdate, etc.
|
||||||
|
|
||||||
LOG.debug( "Dirty checking collections" );
|
LOG.debug( "Dirty checking collections" );
|
||||||
persistenceContext.forEachCollectionEntry( (pc,ce) -> ce.preFlush( pc ), true );
|
final Map<PersistentCollection<?>, CollectionEntry> collectionEntries = persistenceContext.getCollectionEntries();
|
||||||
|
if ( collectionEntries != null ) {
|
||||||
|
for ( Map.Entry<PersistentCollection<?>, CollectionEntry> entry : ( (IdentityMap<PersistentCollection<?>, CollectionEntry>) collectionEntries ).entryArray() ) {
|
||||||
|
entry.getValue().preFlush( entry.getKey() );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -262,14 +270,20 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
||||||
throws HibernateException {
|
throws HibernateException {
|
||||||
LOG.trace( "Processing unreferenced collections" );
|
LOG.trace( "Processing unreferenced collections" );
|
||||||
|
|
||||||
final int count = persistenceContext.getCollectionEntriesSize();
|
final Map<PersistentCollection<?>, CollectionEntry> collectionEntries = persistenceContext.getCollectionEntries();
|
||||||
|
final int count;
|
||||||
persistenceContext.forEachCollectionEntry(
|
if ( collectionEntries == null ) {
|
||||||
(persistentCollection, collectionEntry) -> {
|
count = 0;
|
||||||
if ( !collectionEntry.isReached() && !collectionEntry.isIgnore() ) {
|
}
|
||||||
Collections.processUnreachableCollection( persistentCollection, session );
|
else {
|
||||||
|
count = collectionEntries.size();
|
||||||
|
for ( Map.Entry<PersistentCollection<?>, CollectionEntry> me : ( (IdentityMap<PersistentCollection<?>, CollectionEntry>) collectionEntries ).entryArray() ) {
|
||||||
|
final CollectionEntry ce = me.getValue();
|
||||||
|
if ( !ce.isReached() && !ce.isIgnore() ) {
|
||||||
|
Collections.processUnreachableCollection( me.getKey(), session );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, true );
|
|
||||||
|
|
||||||
// Schedule updates to collections:
|
// Schedule updates to collections:
|
||||||
|
|
||||||
|
|
|
@ -350,8 +350,7 @@ public class DefaultMergeEventListener
|
||||||
.getMappingMetamodel()
|
.getMappingMetamodel()
|
||||||
.getCollectionDescriptor( collectionType.getRole() );
|
.getCollectionDescriptor( collectionType.getRole() );
|
||||||
final CollectionEntry collectionEntry = getSession().getPersistenceContextInternal()
|
final CollectionEntry collectionEntry = getSession().getPersistenceContextInternal()
|
||||||
.getCollectionEntries()
|
.getCollectionEntry( coll );
|
||||||
.get( coll );
|
|
||||||
if ( !coll.equalsSnapshot( persister ) ) {
|
if ( !coll.equalsSnapshot( persister ) ) {
|
||||||
collectionEntry.resetStoredSnapshot( coll, coll.getSnapshot( persister ) );
|
collectionEntry.resetStoredSnapshot( coll, coll.getSnapshot( persister ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public final class IdentityMap<K,V> implements Map<K,V> {
|
||||||
|
|
||||||
private final LinkedHashMap<IdentityKey<K>,V> map;
|
private final LinkedHashMap<IdentityKey<K>,V> map;
|
||||||
|
|
||||||
private transient Entry<IdentityKey<K>,V>[] entryArray = null;
|
private transient Entry<K,V>[] entryArray = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a new instance of this class, with iteration
|
* Return a new instance of this class, with iteration
|
||||||
|
@ -151,15 +151,14 @@ public final class IdentityMap<K,V> implements Map<K,V> {
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( {"unchecked"})
|
public Entry<K,V>[] entryArray() {
|
||||||
public Entry[] entryArray() {
|
|
||||||
if ( entryArray == null ) {
|
if ( entryArray == null ) {
|
||||||
entryArray = new Entry[ map.size() ];
|
entryArray = new Entry[ map.size() ];
|
||||||
final Iterator<Entry<IdentityKey<K>, V>> itr = map.entrySet().iterator();
|
final Iterator<Entry<IdentityKey<K>, V>> itr = map.entrySet().iterator();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while ( itr.hasNext() ) {
|
while ( itr.hasNext() ) {
|
||||||
final Entry<IdentityKey<K>, V> me = itr.next();
|
final Entry<IdentityKey<K>, V> me = itr.next();
|
||||||
entryArray[i++] = new IdentityMapEntry( me.getKey().key, me.getValue() );
|
entryArray[i++] = new IdentityMapEntry<>( me.getKey().key, me.getValue() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return entryArray;
|
return entryArray;
|
||||||
|
|
|
@ -185,7 +185,7 @@ public abstract class AbstractCompositeIdentifierMapping
|
||||||
else {
|
else {
|
||||||
for ( int i = 0; i < size; i++ ) {
|
for ( int i = 0; i < size; i++ ) {
|
||||||
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
||||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
final Object o = embeddableTypeDescriptor.getValue( value, i );
|
||||||
if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
||||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
|
||||||
final ForeignKeyDescriptor fkDescriptor = toOneAttributeMapping.getForeignKeyDescriptor();
|
final ForeignKeyDescriptor fkDescriptor = toOneAttributeMapping.getForeignKeyDescriptor();
|
||||||
|
|
|
@ -56,14 +56,14 @@ public interface AttributeMapping
|
||||||
* Convenient access to getting the value for this attribute from the declarer
|
* Convenient access to getting the value for this attribute from the declarer
|
||||||
*/
|
*/
|
||||||
default Object getValue(Object container) {
|
default Object getValue(Object container) {
|
||||||
return getPropertyAccess().getGetter().get( container );
|
return getDeclaringType().getValue( container, getStateArrayPosition() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenient access to setting the value for this attribute on the declarer
|
* Convenient access to setting the value for this attribute on the declarer
|
||||||
*/
|
*/
|
||||||
default void setValue(Object container, Object value) {
|
default void setValue(Object container, Object value) {
|
||||||
getPropertyAccess().getSetter().set( container, value );
|
getDeclaringType().setValue( container, getStateArrayPosition(), value );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -262,9 +262,8 @@ public interface EmbeddableMappingType extends ManagedMappingType, SelectableMap
|
||||||
default int compare(Object value1, Object value2) {
|
default int compare(Object value1, Object value2) {
|
||||||
final AttributeMappingsList attributeMappings = getAttributeMappings();
|
final AttributeMappingsList attributeMappings = getAttributeMappings();
|
||||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||||
AttributeMapping attributeMapping = attributeMappings.get( i );
|
final AttributeMapping attribute = attributeMappings.get( i );
|
||||||
final Getter getter = attributeMapping.getPropertyAccess().getGetter();
|
final int comparison = attribute.compare( attribute.getValue( value1 ), attribute.getValue( value2 ) );
|
||||||
final int comparison = attributeMapping.compare( getter.get( value1 ), getter.get( value2 ) );
|
|
||||||
if ( comparison != 0 ) {
|
if ( comparison != 0 ) {
|
||||||
return comparison;
|
return comparison;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ public interface ManagedMappingType extends MappingType, FetchableContainer {
|
||||||
* Extract a specific attribute value from the entity instance, by position
|
* Extract a specific attribute value from the entity instance, by position
|
||||||
*/
|
*/
|
||||||
default Object getValue(Object instance, int position) {
|
default Object getValue(Object instance, int position) {
|
||||||
return getAttributeMapping( position ).getValue( instance );
|
return getAttributeMapping( position ).getPropertyAccess().getGetter().get( instance );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,7 +85,7 @@ public interface ManagedMappingType extends MappingType, FetchableContainer {
|
||||||
* Inject a specific attribute value into the entity instance, by position
|
* Inject a specific attribute value into the entity instance, by position
|
||||||
*/
|
*/
|
||||||
default void setValue(Object instance, int position, Object value) {
|
default void setValue(Object instance, int position, Object value) {
|
||||||
getAttributeMapping( position ).setValue( instance, value );
|
getAttributeMapping( position ).getPropertyAccess().getSetter().set( instance, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean anyRequiresAggregateColumnWriter() {
|
default boolean anyRequiresAggregateColumnWriter() {
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
||||||
import org.hibernate.property.access.spi.Getter;
|
import org.hibernate.property.access.spi.Getter;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
|
import org.hibernate.property.access.spi.Setter;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||||
import org.hibernate.sql.results.graph.Fetchable;
|
import org.hibernate.sql.results.graph.Fetchable;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
|
@ -70,6 +71,8 @@ import org.hibernate.type.spi.TypeConfiguration;
|
||||||
public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType {
|
public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType {
|
||||||
final protected MutableAttributeMappingList attributeMappings;
|
final protected MutableAttributeMappingList attributeMappings;
|
||||||
protected SelectableMappings selectableMappings;
|
protected SelectableMappings selectableMappings;
|
||||||
|
protected Getter[] getterCache;
|
||||||
|
protected Setter[] setterCache;
|
||||||
|
|
||||||
public AbstractEmbeddableMapping(MutableAttributeMappingList attributeMappings) {
|
public AbstractEmbeddableMapping(MutableAttributeMappingList attributeMappings) {
|
||||||
this.attributeMappings = attributeMappings;
|
this.attributeMappings = attributeMappings;
|
||||||
|
@ -80,6 +83,16 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
return getRepresentationStrategy().getMappedJavaType();
|
return getRepresentationStrategy().getMappedJavaType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValue(Object instance, int position) {
|
||||||
|
return getterCache[position].get( instance );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(Object instance, int position, Object value) {
|
||||||
|
setterCache[position].set( instance, value );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] getValues(Object compositeInstance) {
|
public Object[] getValues(Object compositeInstance) {
|
||||||
if ( compositeInstance == PropertyAccessStrategyBackRefImpl.UNKNOWN ) {
|
if ( compositeInstance == PropertyAccessStrategyBackRefImpl.UNKNOWN ) {
|
||||||
|
@ -93,10 +106,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
|
|
||||||
final Object[] results = new Object[getNumberOfAttributeMappings()];
|
final Object[] results = new Object[getNumberOfAttributeMappings()];
|
||||||
for ( int i = 0; i < results.length; i++ ) {
|
for ( int i = 0; i < results.length; i++ ) {
|
||||||
final Getter getter = getAttributeMapping( i ).getAttributeMetadata()
|
results[i] = getValue( compositeInstance, i );
|
||||||
.getPropertyAccess()
|
|
||||||
.getGetter();
|
|
||||||
results[i] = getter.get( compositeInstance );
|
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +119,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for ( int i = 0; i < values.length; i++ ) {
|
for ( int i = 0; i < values.length; i++ ) {
|
||||||
getAttributeMapping( i ).getPropertyAccess().getSetter().set( component, values[i] );
|
setValue( component, i,values[i] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,6 +225,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
}
|
}
|
||||||
mappings.add( attributeMapping );
|
mappings.add( attributeMapping );
|
||||||
}
|
}
|
||||||
|
buildGetterSetterCache();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,7 +697,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
if ( attributeMapping instanceof PluralAttributeMapping ) {
|
if ( attributeMapping instanceof PluralAttributeMapping ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
final Object o = getValue( value, i );
|
||||||
span += attributeMapping.forEachJdbcValue( o, span + offset, x, y, valuesConsumer, session );
|
span += attributeMapping.forEachJdbcValue( o, span + offset, x, y, valuesConsumer, session );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -722,10 +733,24 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
);
|
);
|
||||||
|
|
||||||
this.selectableMappings = new SelectableMappingsImpl( selectableMappings.toArray( new SelectableMapping[0] ) );
|
this.selectableMappings = new SelectableMappingsImpl( selectableMappings.toArray( new SelectableMapping[0] ) );
|
||||||
|
buildGetterSetterCache();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void buildGetterSetterCache() {
|
||||||
|
final int propertySpan = attributeMappings.size();
|
||||||
|
final Getter[] getterCache = new Getter[propertySpan];
|
||||||
|
final Setter[] setterCache = new Setter[propertySpan];
|
||||||
|
for ( int i = 0; i < propertySpan; i++ ) {
|
||||||
|
final PropertyAccess propertyAccess = attributeMappings.get( i ).getPropertyAccess();
|
||||||
|
getterCache[i] = propertyAccess.getGetter();
|
||||||
|
setterCache[i] = propertyAccess.getSetter();
|
||||||
|
}
|
||||||
|
this.getterCache = getterCache;
|
||||||
|
this.setterCache = setterCache;
|
||||||
|
}
|
||||||
|
|
||||||
private static MutabilityPlan<?> getMutabilityPlan(boolean updateable) {
|
private static MutabilityPlan<?> getMutabilityPlan(boolean updateable) {
|
||||||
if ( updateable ) {
|
if ( updateable ) {
|
||||||
return new MutabilityPlan<>() {
|
return new MutabilityPlan<>() {
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||||
import org.hibernate.metamodel.mapping.SelectableMappings;
|
import org.hibernate.metamodel.mapping.SelectableMappings;
|
||||||
|
@ -658,7 +659,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme
|
||||||
if ( !attributeMapping.isPluralAttributeMapping() ) {
|
if ( !attributeMapping.isPluralAttributeMapping() ) {
|
||||||
final Object attributeValue = domainValue == null
|
final Object attributeValue = domainValue == null
|
||||||
? null
|
? null
|
||||||
: attributeMapping.getPropertyAccess().getGetter().get( domainValue );
|
: getValue( domainValue, i );
|
||||||
span += attributeMapping.breakDownJdbcValues(
|
span += attributeMapping.breakDownJdbcValues(
|
||||||
attributeValue,
|
attributeValue,
|
||||||
offset + span,
|
offset + span,
|
||||||
|
|
|
@ -143,7 +143,9 @@ public class EmbeddedAttributeMapping
|
||||||
MappingModelCreationProcess creationProcess) {
|
MappingModelCreationProcess creationProcess) {
|
||||||
super(
|
super(
|
||||||
inverseModelPart.getFetchableName(),
|
inverseModelPart.getFetchableName(),
|
||||||
-1,
|
inverseModelPart.asAttributeMapping() != null
|
||||||
|
? inverseModelPart.asAttributeMapping().getStateArrayPosition()
|
||||||
|
: -1,
|
||||||
inverseModelPart.getFetchableKey(),
|
inverseModelPart.getFetchableKey(),
|
||||||
inverseModelPart.asAttributeMapping() != null
|
inverseModelPart.asAttributeMapping() != null
|
||||||
? inverseModelPart.asAttributeMapping().getAttributeMetadata()
|
? inverseModelPart.asAttributeMapping().getAttributeMetadata()
|
||||||
|
|
|
@ -165,7 +165,7 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
||||||
|
|
||||||
for ( int i = 0; i < propertyValues.length; i++ ) {
|
for ( int i = 0; i < propertyValues.length; i++ ) {
|
||||||
final AttributeMapping attributeMapping = virtualIdEmbeddable.getAttributeMapping( i );
|
final AttributeMapping attributeMapping = virtualIdEmbeddable.getAttributeMapping( i );
|
||||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( entity );
|
final Object o = attributeMapping.getValue( entity );
|
||||||
if ( o == null ) {
|
if ( o == null ) {
|
||||||
final AttributeMapping idClassAttributeMapping = getAttributeMapping( i );
|
final AttributeMapping idClassAttributeMapping = getAttributeMapping( i );
|
||||||
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
||||||
|
@ -210,7 +210,7 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
||||||
virtualIdEmbeddable.forEachAttribute(
|
virtualIdEmbeddable.forEachAttribute(
|
||||||
(position, virtualIdAttribute) -> {
|
(position, virtualIdAttribute) -> {
|
||||||
final AttributeMapping idClassAttribute = attributeMappings.get( position );
|
final AttributeMapping idClassAttribute = attributeMappings.get( position );
|
||||||
Object o = idClassAttribute.getPropertyAccess().getGetter().get( id );
|
Object o = idClassAttribute.getValue( id );
|
||||||
if ( virtualIdAttribute instanceof ToOneAttributeMapping && !( idClassAttribute instanceof ToOneAttributeMapping ) ) {
|
if ( virtualIdAttribute instanceof ToOneAttributeMapping && !( idClassAttribute instanceof ToOneAttributeMapping ) ) {
|
||||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) virtualIdAttribute;
|
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) virtualIdAttribute;
|
||||||
final EntityPersister entityPersister = toOneAttributeMapping.getEntityMappingType()
|
final EntityPersister entityPersister = toOneAttributeMapping.getEntityMappingType()
|
||||||
|
|
|
@ -198,7 +198,7 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
|
||||||
final Object[] propertyValues = new Object[embeddableTypeDescriptor.getNumberOfAttributeMappings()];
|
final Object[] propertyValues = new Object[embeddableTypeDescriptor.getNumberOfAttributeMappings()];
|
||||||
for ( int i = 0; i < propertyValues.length; i++ ) {
|
for ( int i = 0; i < propertyValues.length; i++ ) {
|
||||||
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
||||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( entity );
|
final Object o = attributeMapping.getValue( entity );
|
||||||
if ( o == null ) {
|
if ( o == null ) {
|
||||||
final AttributeMapping idClassAttributeMapping = identifierValueMapper.getAttributeMapping( i );
|
final AttributeMapping idClassAttributeMapping = identifierValueMapper.getAttributeMapping( i );
|
||||||
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
||||||
|
@ -242,7 +242,7 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
|
||||||
for ( int position = 0; position < propertyValues.length; position++ ) {
|
for ( int position = 0; position < propertyValues.length; position++ ) {
|
||||||
final AttributeMapping attribute = embeddableTypeDescriptor.getAttributeMapping( position );
|
final AttributeMapping attribute = embeddableTypeDescriptor.getAttributeMapping( position );
|
||||||
final AttributeMapping mappedIdAttributeMapping = identifierValueMapper.getAttributeMapping( position );
|
final AttributeMapping mappedIdAttributeMapping = identifierValueMapper.getAttributeMapping( position );
|
||||||
Object o = mappedIdAttributeMapping.getPropertyAccess().getGetter().get( id );
|
Object o = mappedIdAttributeMapping.getValue( 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()
|
||||||
|
@ -253,11 +253,8 @@ public class InverseNonAggregatedIdentifierMapping extends EmbeddedAttributeMapp
|
||||||
// use the managed object i.e. proxy or initialized entity
|
// use the managed object i.e. proxy or initialized entity
|
||||||
o = holder == null ? null : holder.getManagedObject();
|
o = holder == null ? null : holder.getManagedObject();
|
||||||
if ( o == null ) {
|
if ( o == null ) {
|
||||||
o = entityDescriptor
|
o = entityDescriptor.findAttributeMapping( toOneAttributeMapping.getAttributeName() )
|
||||||
.findAttributeMapping( toOneAttributeMapping.getAttributeName() )
|
.getValue( entity );
|
||||||
.getPropertyAccess()
|
|
||||||
.getGetter()
|
|
||||||
.get( entity );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
propertyValues[position] = o;
|
propertyValues[position] = o;
|
||||||
|
|
|
@ -232,7 +232,7 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
||||||
final Object[] propertyValues = new Object[embeddableTypeDescriptor.getNumberOfAttributeMappings()];
|
final Object[] propertyValues = new Object[embeddableTypeDescriptor.getNumberOfAttributeMappings()];
|
||||||
for ( int i = 0; i < propertyValues.length; i++ ) {
|
for ( int i = 0; i < propertyValues.length; i++ ) {
|
||||||
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
|
||||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( entity );
|
final Object o = attributeMapping.getValue( entity );
|
||||||
if ( o == null ) {
|
if ( o == null ) {
|
||||||
final AttributeMapping idClassAttributeMapping = identifierValueMapper.getAttributeMapping( i );
|
final AttributeMapping idClassAttributeMapping = identifierValueMapper.getAttributeMapping( i );
|
||||||
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
if ( idClassAttributeMapping.getPropertyAccess().getGetter().getReturnTypeClass().isPrimitive() ) {
|
||||||
|
@ -276,7 +276,7 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
||||||
for ( int i = 0; i < propertyValues.length; i++ ) {
|
for ( int i = 0; i < propertyValues.length; i++ ) {
|
||||||
final AttributeMapping attribute = embeddableTypeDescriptor.getAttributeMapping( i );
|
final AttributeMapping attribute = embeddableTypeDescriptor.getAttributeMapping( i );
|
||||||
final AttributeMapping mappedIdAttributeMapping = identifierValueMapper.getAttributeMapping( i );
|
final AttributeMapping mappedIdAttributeMapping = identifierValueMapper.getAttributeMapping( i );
|
||||||
Object o = mappedIdAttributeMapping.getPropertyAccess().getGetter().get( id );
|
Object o = mappedIdAttributeMapping.getValue( 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().getEntityPersister();
|
final EntityPersister entityPersister = toOneAttributeMapping.getEntityMappingType().getEntityPersister();
|
||||||
|
|
|
@ -247,15 +247,32 @@ public class VirtualIdEmbeddable extends AbstractEmbeddableMapping implements Id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areEqual(Object one, Object other, SharedSessionContractImplementor session) {
|
||||||
|
final IdClassEmbeddable idClassEmbeddable = idMapping.getIdClassEmbeddable();
|
||||||
|
if ( idClassEmbeddable != null ) {
|
||||||
|
return idClassEmbeddable.areEqual( one, other, session );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final AttributeMappingsList attributeMappings = getAttributeMappings();
|
||||||
|
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||||
|
final AttributeMapping attribute = attributeMappings.get( i );
|
||||||
|
if ( !attribute.areEqual( attribute.getValue( one ), attribute.getValue( other ), session ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(Object value1, Object value2) {
|
public int compare(Object value1, Object value2) {
|
||||||
final IdClassEmbeddable idClassEmbeddable = idMapping.getIdClassEmbeddable();
|
final IdClassEmbeddable idClassEmbeddable = idMapping.getIdClassEmbeddable();
|
||||||
if ( idClassEmbeddable != null ) {
|
if ( idClassEmbeddable != null ) {
|
||||||
final AttributeMappingsList attributeMappings = idClassEmbeddable.getAttributeMappings();
|
final AttributeMappingsList attributeMappings = idClassEmbeddable.getAttributeMappings();
|
||||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
final AttributeMapping attribute = attributeMappings.get( i );
|
||||||
final Getter getter = attributeMapping.getPropertyAccess().getGetter();
|
final int comparison = attribute.compare( attribute.getValue( value1 ), attribute.getValue( value2 ) );
|
||||||
final int comparison = attributeMapping.compare( getter.get( value1 ), getter.get( value2 ) );
|
|
||||||
if ( comparison != 0 ) {
|
if ( comparison != 0 ) {
|
||||||
return comparison;
|
return comparison;
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,6 +221,7 @@ import org.hibernate.persister.entity.mutation.UpdateCoordinatorNoOp;
|
||||||
import org.hibernate.persister.entity.mutation.UpdateCoordinatorStandard;
|
import org.hibernate.persister.entity.mutation.UpdateCoordinatorStandard;
|
||||||
import org.hibernate.persister.internal.SqlFragmentPredicate;
|
import org.hibernate.persister.internal.SqlFragmentPredicate;
|
||||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||||
|
import org.hibernate.property.access.spi.Getter;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
import org.hibernate.property.access.spi.Setter;
|
import org.hibernate.property.access.spi.Setter;
|
||||||
import org.hibernate.query.PathException;
|
import org.hibernate.query.PathException;
|
||||||
|
@ -452,6 +453,9 @@ public abstract class AbstractEntityPersister
|
||||||
private AttributeMappingsList attributeMappings;
|
private AttributeMappingsList attributeMappings;
|
||||||
protected AttributeMappingsMap declaredAttributeMappings = AttributeMappingsMap.builder().build();
|
protected AttributeMappingsMap declaredAttributeMappings = AttributeMappingsMap.builder().build();
|
||||||
protected AttributeMappingsList staticFetchableList;
|
protected AttributeMappingsList staticFetchableList;
|
||||||
|
// We build a cache for getters and setters to avoid megamorphic calls
|
||||||
|
private Getter[] getterCache;
|
||||||
|
private Setter[] setterCache;
|
||||||
|
|
||||||
private final String queryLoaderName;
|
private final String queryLoaderName;
|
||||||
|
|
||||||
|
@ -4448,23 +4452,19 @@ public abstract class AbstractEntityPersister
|
||||||
accessOptimizer.setPropertyValues( object, values );
|
accessOptimizer.setPropertyValues( object, values );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( hasSubclasses() ) {
|
final BytecodeEnhancementMetadata enhancementMetadata = entityMetamodel.getBytecodeEnhancementMetadata();
|
||||||
|
final AttributeMappingsList attributeMappings = getAttributeMappings();
|
||||||
|
if ( enhancementMetadata.isEnhancedForLazyLoading() ) {
|
||||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||||
final Object value = values[i];
|
final Object value = values[i];
|
||||||
if ( value != UNFETCHED_PROPERTY ) {
|
if ( value != UNFETCHED_PROPERTY ) {
|
||||||
final Setter setter = attributeMappings.get( i ).getPropertyAccess().getSetter();
|
setterCache[i].set( object, value );
|
||||||
setter.set( object, value );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for ( int i = 0; i < staticFetchableList.size(); i++ ) {
|
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||||
final AttributeMapping attribute = staticFetchableList.get( i );
|
setterCache[i].set( object, values[i] );
|
||||||
final Object value = values[i];
|
|
||||||
if ( value != UNFETCHED_PROPERTY ) {
|
|
||||||
final Setter setter = attribute.getPropertyAccess().getSetter();
|
|
||||||
setter.set( object, value );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4472,8 +4472,7 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPropertyValue(Object object, int i, Object value) {
|
public void setPropertyValue(Object object, int i, Object value) {
|
||||||
final String propertyName = getPropertyNames()[i];
|
setterCache[i].set( object, value );
|
||||||
setPropertyValue( object, propertyName, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4483,19 +4482,26 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final BytecodeEnhancementMetadata enhancementMetadata = entityMetamodel.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata enhancementMetadata = entityMetamodel.getBytecodeEnhancementMetadata();
|
||||||
|
final AttributeMappingsList attributeMappings = getAttributeMappings();
|
||||||
|
final Object[] values = new Object[attributeMappings.size()];
|
||||||
|
if ( enhancementMetadata.isEnhancedForLazyLoading() ) {
|
||||||
final LazyAttributesMetadata lazyAttributesMetadata = enhancementMetadata.getLazyAttributesMetadata();
|
final LazyAttributesMetadata lazyAttributesMetadata = enhancementMetadata.getLazyAttributesMetadata();
|
||||||
final Object[] values = new Object[ getNumberOfAttributeMappings() ];
|
|
||||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||||
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
final AttributeMapping attributeMapping = attributeMappings.get( i );
|
||||||
final AttributeMetadata attributeMetadata = attributeMapping.getAttributeMetadata();
|
|
||||||
if ( !lazyAttributesMetadata.isLazyAttribute( attributeMapping.getAttributeName() )
|
if ( !lazyAttributesMetadata.isLazyAttribute( attributeMapping.getAttributeName() )
|
||||||
|| enhancementMetadata.isAttributeLoaded( object, attributeMapping.getAttributeName() ) ) {
|
|| enhancementMetadata.isAttributeLoaded( object, attributeMapping.getAttributeName() ) ) {
|
||||||
values[i] = attributeMetadata.getPropertyAccess().getGetter().get( object );
|
values[i] = getterCache[i].get( object );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
values[i] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
|
values[i] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||||
|
values[i] = getterCache[i].get( object );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
@ -4503,7 +4509,7 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getPropertyValue(Object object, int i) {
|
public Object getPropertyValue(Object object, int i) {
|
||||||
return attributeMappings.get( i ).getAttributeMetadata().getPropertyAccess().getGetter().get( object );
|
return getterCache[i].get( object );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4516,7 +4522,7 @@ public abstract class AbstractEntityPersister
|
||||||
ManagedMappingType baseValueType = null;
|
ManagedMappingType baseValueType = null;
|
||||||
Object baseValue = null;
|
Object baseValue = null;
|
||||||
if ( attributeMapping != null ) {
|
if ( attributeMapping != null ) {
|
||||||
baseValue = attributeMapping.getAttributeMetadata().getPropertyAccess().getGetter().get( object );
|
baseValue = getterCache[attributeMapping.getStateArrayPosition()].get( object );
|
||||||
if ( dotIndex != -1 ) {
|
if ( dotIndex != -1 ) {
|
||||||
baseValueType = (ManagedMappingType) attributeMapping.getMappedType();
|
baseValueType = (ManagedMappingType) attributeMapping.getMappedType();
|
||||||
}
|
}
|
||||||
|
@ -4527,7 +4533,7 @@ public abstract class AbstractEntityPersister
|
||||||
final AttributeMapping mapping = embeddedAttributeMapping == null ? null
|
final AttributeMapping mapping = embeddedAttributeMapping == null ? null
|
||||||
: embeddedAttributeMapping.getMappedType().findAttributeMapping( basePropertyName );
|
: embeddedAttributeMapping.getMappedType().findAttributeMapping( basePropertyName );
|
||||||
if ( mapping != null ) {
|
if ( mapping != null ) {
|
||||||
baseValue = mapping.getAttributeMetadata().getPropertyAccess().getGetter().get( object );
|
baseValue = mapping.getValue( object );
|
||||||
if ( dotIndex != -1 ) {
|
if ( dotIndex != -1 ) {
|
||||||
baseValueType = (ManagedMappingType) mapping.getMappedType();
|
baseValueType = (ManagedMappingType) mapping.getMappedType();
|
||||||
}
|
}
|
||||||
|
@ -4549,7 +4555,7 @@ public abstract class AbstractEntityPersister
|
||||||
final int endIndex = nextDotIndex == -1 ? propertyName.length() : nextDotIndex;
|
final int endIndex = nextDotIndex == -1 ? propertyName.length() : nextDotIndex;
|
||||||
final AttributeMapping attributeMapping =
|
final AttributeMapping attributeMapping =
|
||||||
baseValueType.findAttributeMapping( propertyName.substring( dotIndex + 1, endIndex ) );
|
baseValueType.findAttributeMapping( propertyName.substring( dotIndex + 1, endIndex ) );
|
||||||
baseValue = attributeMapping.getAttributeMetadata().getPropertyAccess().getGetter().get( baseValue );
|
baseValue = attributeMapping.getValue( baseValue );
|
||||||
baseValueType = nextDotIndex == -1 ? null : (ManagedMappingType) attributeMapping.getMappedType();
|
baseValueType = nextDotIndex == -1 ? null : (ManagedMappingType) attributeMapping.getMappedType();
|
||||||
return getPropertyValue( baseValue, baseValueType, propertyName, nextDotIndex );
|
return getPropertyValue( baseValue, baseValueType, propertyName, nextDotIndex );
|
||||||
}
|
}
|
||||||
|
@ -4669,9 +4675,7 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
final Object[] result = new Object[attributeMappings.size()];
|
final Object[] result = new Object[attributeMappings.size()];
|
||||||
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||||
result[i] = attributeMappings.get( i )
|
result[i] = getterCache[i].getForInsert( entity, mergeMap, session );
|
||||||
.getPropertyAccess().getGetter()
|
|
||||||
.getForInsert( entity, mergeMap, session );
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -4793,8 +4797,7 @@ public abstract class AbstractEntityPersister
|
||||||
@Override
|
@Override
|
||||||
public void setPropertyValue(Object object, String propertyName, Object value) {
|
public void setPropertyValue(Object object, String propertyName, Object value) {
|
||||||
final AttributeMapping attributeMapping = findSubPart( propertyName, this ).asAttributeMapping();
|
final AttributeMapping attributeMapping = findSubPart( propertyName, this ).asAttributeMapping();
|
||||||
final AttributeMetadata attributeMetadata = attributeMapping.getAttributeMetadata();
|
setterCache[attributeMapping.getStateArrayPosition()].set( object, value );
|
||||||
attributeMetadata.getPropertyAccess().getSetter().set( object, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getTableId(String tableName, String[] tables) {
|
public static int getTableId(String tableName, String[] tables) {
|
||||||
|
@ -5912,6 +5915,15 @@ public abstract class AbstractEntityPersister
|
||||||
builder.add( am );
|
builder.add( am );
|
||||||
}
|
}
|
||||||
this.attributeMappings = builder.build();
|
this.attributeMappings = builder.build();
|
||||||
|
final Getter[] getters = new Getter[attributeMappings.size()];
|
||||||
|
final Setter[] setters = new Setter[attributeMappings.size()];
|
||||||
|
for ( int i = 0; i < attributeMappings.size(); i++ ) {
|
||||||
|
final PropertyAccess propertyAccess = attributeMappings.get( i ).getAttributeMetadata().getPropertyAccess();
|
||||||
|
getters[i] = propertyAccess.getGetter();
|
||||||
|
setters[i] = propertyAccess.getSetter();
|
||||||
|
}
|
||||||
|
this.getterCache = getters;
|
||||||
|
this.setterCache = setters;
|
||||||
// subclasses? it depends on the usage
|
// subclasses? it depends on the usage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -522,7 +522,7 @@ public interface EntityPersister extends EntityMappingType, RootTableGroupProduc
|
||||||
else {
|
else {
|
||||||
for ( int i = 0; i < getNumberOfAttributeMappings(); i++ ) {
|
for ( int i = 0; i < getNumberOfAttributeMappings(); i++ ) {
|
||||||
final AttributeMapping attributeMapping = getAttributeMapping( i );
|
final AttributeMapping attributeMapping = getAttributeMapping( i );
|
||||||
final Object attributeValue = attributeMapping.getPropertyAccess().getGetter().get( domainValue );
|
final Object attributeValue = attributeMapping.getValue( domainValue );
|
||||||
span += attributeMapping.breakDownJdbcValues(
|
span += attributeMapping.breakDownJdbcValues(
|
||||||
attributeValue,
|
attributeValue,
|
||||||
offset + span,
|
offset + span,
|
||||||
|
|
|
@ -235,28 +235,22 @@ public class AnonymousTupleEmbeddableValuedModelPart implements EmbeddableValued
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] getValues(Object instance) {
|
public Object[] getValues(Object instance) {
|
||||||
return existingModelPartContainer.getEmbeddableTypeDescriptor()
|
return existingModelPartContainer.getEmbeddableTypeDescriptor().getValues( instance );
|
||||||
.getValues( instance );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getValue(Object instance, int position) {
|
public Object getValue(Object instance, int position) {
|
||||||
return existingModelPartContainer.getEmbeddableTypeDescriptor()
|
return existingModelPartContainer.getEmbeddableTypeDescriptor().getValue( instance, position );
|
||||||
.getAttributeMapping( position )
|
|
||||||
.getValue( instance );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setValues(Object instance, Object[] resolvedValues) {
|
public void setValues(Object instance, Object[] resolvedValues) {
|
||||||
existingModelPartContainer.getEmbeddableTypeDescriptor()
|
existingModelPartContainer.getEmbeddableTypeDescriptor().setValues( instance, resolvedValues );
|
||||||
.setValues( instance, resolvedValues );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setValue(Object instance, int position, Object value) {
|
public void setValue(Object instance, int position, Object value) {
|
||||||
existingModelPartContainer.getEmbeddableTypeDescriptor()
|
existingModelPartContainer.getEmbeddableTypeDescriptor().setValue( instance, position, value );
|
||||||
.getAttributeMapping( position )
|
|
||||||
.setValue( instance, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -198,9 +198,7 @@ public class AnonymousTupleEntityValuedModelPart
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getValue(Object instance, int position) {
|
public Object getValue(Object instance, int position) {
|
||||||
return delegate.getEntityMappingType()
|
return delegate.getEntityMappingType().getValue( instance, position );
|
||||||
.getAttributeMapping( position )
|
|
||||||
.getValue( instance );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -210,9 +208,7 @@ public class AnonymousTupleEntityValuedModelPart
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setValue(Object instance, int position, Object value) {
|
public void setValue(Object instance, int position, Object value) {
|
||||||
delegate.getEntityMappingType()
|
delegate.getEntityMappingType().setValue( instance, position, value );
|
||||||
.getAttributeMapping( position )
|
|
||||||
.setValue( instance, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import jakarta.persistence.CacheRetrieveMode;
|
import jakarta.persistence.CacheRetrieveMode;
|
||||||
import jakarta.persistence.CacheStoreMode;
|
import jakarta.persistence.CacheStoreMode;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import org.hibernate.CacheMode;
|
import org.hibernate.CacheMode;
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
|
@ -57,13 +58,13 @@ public interface QueryOptions {
|
||||||
* Transformer applied to the query to transform the structure of each "row"
|
* Transformer applied to the query to transform the structure of each "row"
|
||||||
* in the results
|
* in the results
|
||||||
*/
|
*/
|
||||||
TupleTransformer<?> getTupleTransformer();
|
@Nullable TupleTransformer<?> getTupleTransformer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transformer applied to the query to transform the structure of the
|
* Transformer applied to the query to transform the structure of the
|
||||||
* overall results
|
* overall results
|
||||||
*/
|
*/
|
||||||
ResultListTransformer<?> getResultListTransformer();
|
@Nullable ResultListTransformer<?> getResultListTransformer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should results from the query be cached?
|
* Should results from the query be cached?
|
||||||
|
|
|
@ -183,11 +183,10 @@ class CompositeGeneratorBuilder {
|
||||||
for ( int i = 0; i < size; i++ ) {
|
for ( int i = 0; i < size; i++ ) {
|
||||||
final Generator generator = generators.get(i);
|
final Generator generator = generators.get(i);
|
||||||
if ( generator != null ) {
|
if ( generator != null ) {
|
||||||
final AttributeMapping attributeMapping = descriptor.getAttributeMapping(i);
|
final Object value = descriptor.getValue( currentValue, i );
|
||||||
final Object value = attributeMapping.getPropertyAccess().getGetter().get( currentValue );
|
|
||||||
final Object generatedValue = ((BeforeExecutionGenerator) generator)
|
final Object generatedValue = ((BeforeExecutionGenerator) generator)
|
||||||
.generate( session, owner, value, eventType );
|
.generate( session, owner, value, eventType );
|
||||||
attributeMapping.getPropertyAccess().getSetter().set( currentValue, generatedValue );
|
descriptor.setValue( currentValue, i, generatedValue );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return currentValue;
|
return currentValue;
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class LazyProxyBytecodeEnhancementCollectionInitializationTest
|
||||||
Parent parent = s.getReference( Parent.class, 1 );
|
Parent parent = s.getReference( Parent.class, 1 );
|
||||||
assertThat( Hibernate.isPropertyInitialized( parent, "children") ).isFalse();
|
assertThat( Hibernate.isPropertyInitialized( parent, "children") ).isFalse();
|
||||||
assertThat( s.unwrap( SessionImplementor.class ).getPersistenceContext().getCollectionEntries() )
|
assertThat( s.unwrap( SessionImplementor.class ).getPersistenceContext().getCollectionEntries() )
|
||||||
.isEmpty();
|
.isNullOrEmpty();
|
||||||
|
|
||||||
// Accessing a collection property on a lazy proxy initializes the property and instantiates the collection,
|
// Accessing a collection property on a lazy proxy initializes the property and instantiates the collection,
|
||||||
// but does not initialize the collection.
|
// but does not initialize the collection.
|
||||||
|
|
Loading…
Reference in New Issue