mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-16 16:15:06 +00:00
HHH-16728 Optimise iteration of AssociationType properties within a Persister
This commit is contained in:
parent
0d58a2410c
commit
2b92c3dbe5
@ -120,6 +120,7 @@
|
|||||||
import org.hibernate.internal.util.LazyValue;
|
import org.hibernate.internal.util.LazyValue;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.internal.util.collections.LockModeEnumMap;
|
import org.hibernate.internal.util.collections.LockModeEnumMap;
|
||||||
import org.hibernate.jdbc.Expectation;
|
import org.hibernate.jdbc.Expectation;
|
||||||
import org.hibernate.jdbc.TooManyRowsAffectedException;
|
import org.hibernate.jdbc.TooManyRowsAffectedException;
|
||||||
@ -279,6 +280,7 @@
|
|||||||
import org.hibernate.tuple.NonIdentifierAttribute;
|
import org.hibernate.tuple.NonIdentifierAttribute;
|
||||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||||
import org.hibernate.type.AnyType;
|
import org.hibernate.type.AnyType;
|
||||||
|
import org.hibernate.type.AssociationType;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
@ -464,6 +466,8 @@ public abstract class AbstractEntityPersister
|
|||||||
|
|
||||||
private final boolean implementsLifecycle;
|
private final boolean implementsLifecycle;
|
||||||
|
|
||||||
|
private List<UniqueKeyEntry> uniqueKeyEntries = null; //lazily initialized
|
||||||
|
|
||||||
@Deprecated(since = "6.0")
|
@Deprecated(since = "6.0")
|
||||||
public AbstractEntityPersister(
|
public AbstractEntityPersister(
|
||||||
final PersistentClass persistentClass,
|
final PersistentClass persistentClass,
|
||||||
@ -1166,6 +1170,30 @@ public boolean canUseReferenceCacheEntries() {
|
|||||||
return useReferenceCacheEntries;
|
return useReferenceCacheEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<UniqueKeyEntry> uniqueKeyEntries() {
|
||||||
|
if ( this.uniqueKeyEntries == null ) {
|
||||||
|
this.uniqueKeyEntries = initUniqueKeyEntries( this );
|
||||||
|
}
|
||||||
|
return this.uniqueKeyEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<UniqueKeyEntry> initUniqueKeyEntries(final AbstractEntityPersister aep) {
|
||||||
|
ArrayList<UniqueKeyEntry> uniqueKeys = new ArrayList();
|
||||||
|
for ( Type propertyType : aep.getPropertyTypes() ) {
|
||||||
|
if ( propertyType instanceof AssociationType ) {
|
||||||
|
final AssociationType associationType = (AssociationType) propertyType;
|
||||||
|
final String ukName = associationType.getLHSPropertyName();
|
||||||
|
if ( ukName != null ) {
|
||||||
|
final int index = aep.findAttributeMapping( ukName ).getStateArrayPosition();
|
||||||
|
final Type type = aep.getPropertyTypes()[index];
|
||||||
|
uniqueKeys.add( new UniqueKeyEntry( ukName, index, type ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CollectionHelper.toSmallList( uniqueKeys );
|
||||||
|
}
|
||||||
|
|
||||||
protected Map<String, SingleIdArrayLoadPlan> getLazyLoadPlanByFetchGroup() {
|
protected Map<String, SingleIdArrayLoadPlan> getLazyLoadPlanByFetchGroup() {
|
||||||
final BytecodeEnhancementMetadata metadata = entityMetamodel.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata metadata = entityMetamodel.getBytecodeEnhancementMetadata();
|
||||||
return metadata.isEnhancedForLazyLoading() && metadata.getLazyAttributesMetadata().hasLazyAttributes()
|
return metadata.isEnhancedForLazyLoading() && metadata.getLazyAttributesMetadata().hasLazyAttributes()
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
@ -1075,4 +1076,10 @@ default int[] resolveDirtyAttributeIndexes(
|
|||||||
@Deprecated(since = "6.2")
|
@Deprecated(since = "6.2")
|
||||||
String ENTITY_ID = "id";
|
String ENTITY_ID = "id";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Metadata for each unique key defined
|
||||||
|
*/
|
||||||
|
@Incubating
|
||||||
|
Iterable<UniqueKeyEntry> uniqueKeyEntries();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.persister.entity;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Useful metadata representing a unique key within a Persister
|
||||||
|
*/
|
||||||
|
public final class UniqueKeyEntry {
|
||||||
|
|
||||||
|
private final String uniqueKeyName;
|
||||||
|
private final int stateArrayPosition;
|
||||||
|
private final Type propertyType;
|
||||||
|
|
||||||
|
public UniqueKeyEntry(final String uniqueKeyName, final int stateArrayPosition, final Type propertyType) {
|
||||||
|
this.uniqueKeyName = Objects.requireNonNull( uniqueKeyName );
|
||||||
|
this.stateArrayPosition = stateArrayPosition;
|
||||||
|
this.propertyType = Objects.requireNonNull( propertyType );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUniqueKeyName() {
|
||||||
|
return this.uniqueKeyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStateArrayPosition() {
|
||||||
|
return this.stateArrayPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getPropertyType() {
|
||||||
|
return this.propertyType;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -41,6 +41,7 @@
|
|||||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.entity.UniqueKeyEntry;
|
||||||
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
||||||
import org.hibernate.proxy.LazyInitializer;
|
import org.hibernate.proxy.LazyInitializer;
|
||||||
import org.hibernate.proxy.map.MapProxy;
|
import org.hibernate.proxy.map.MapProxy;
|
||||||
@ -1034,32 +1035,27 @@ private void putInCache(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void registerPossibleUniqueKeyEntries(Object toInitialize, SharedSessionContractImplementor session) {
|
protected void registerPossibleUniqueKeyEntries(final Object toInitialize, final SharedSessionContractImplementor session) {
|
||||||
for ( Type propertyType : concreteDescriptor.getPropertyTypes() ) {
|
for ( UniqueKeyEntry entry : concreteDescriptor.uniqueKeyEntries() ) {
|
||||||
if ( propertyType instanceof AssociationType ) {
|
final String ukName = entry.getUniqueKeyName();
|
||||||
final AssociationType associationType = (AssociationType) propertyType;
|
final int index = entry.getStateArrayPosition();//concreteDescriptor.findAttributeMapping( ukName ).getStateArrayPosition();
|
||||||
final String ukName = associationType.getLHSPropertyName();
|
final Type type = entry.getPropertyType();//concreteDescriptor.getPropertyTypes()[index];
|
||||||
if ( ukName != null ) {
|
|
||||||
final int index = concreteDescriptor.findAttributeMapping( ukName ).getStateArrayPosition();
|
|
||||||
final Type type = concreteDescriptor.getPropertyTypes()[index];
|
|
||||||
|
|
||||||
// polymorphism not really handled completely correctly,
|
// polymorphism not really handled completely correctly,
|
||||||
// perhaps...well, actually its ok, assuming that the
|
// perhaps...well, actually its ok, assuming that the
|
||||||
// entity name used in the lookup is the same as the
|
// entity name used in the lookup is the same as the
|
||||||
// one used here, which it will be
|
// one used here, which it will be
|
||||||
|
|
||||||
if ( resolvedEntityState[index] != null ) {
|
if ( resolvedEntityState[index] != null ) {
|
||||||
final EntityUniqueKey euk = new EntityUniqueKey(
|
final EntityUniqueKey euk = new EntityUniqueKey(
|
||||||
concreteDescriptor.getRootEntityDescriptor().getEntityName(),
|
concreteDescriptor.getRootEntityDescriptor().getEntityName(),
|
||||||
//polymorphism comment above
|
//polymorphism comment above
|
||||||
ukName,
|
ukName,
|
||||||
resolvedEntityState[index],
|
resolvedEntityState[index],
|
||||||
type,
|
type,
|
||||||
session.getFactory()
|
session.getFactory()
|
||||||
);
|
);
|
||||||
session.getPersistenceContextInternal().addEntity( euk, toInitialize );
|
session.getPersistenceContextInternal().addEntity( euk, toInitialize );
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
|
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.entity.UniqueKeyEntry;
|
||||||
import org.hibernate.persister.spi.PersisterClassResolver;
|
import org.hibernate.persister.spi.PersisterClassResolver;
|
||||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
|
||||||
@ -758,6 +759,11 @@ public boolean canUseReferenceCacheEntries() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<UniqueKeyEntry> uniqueKeyEntries() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAffectedByEnabledFilters(LoadQueryInfluencers influencers) {
|
public boolean isAffectedByEnabledFilters(LoadQueryInfluencers influencers) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
import org.hibernate.orm.test.jpa.SettingsGenerator;
|
import org.hibernate.orm.test.jpa.SettingsGenerator;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.entity.UniqueKeyEntry;
|
||||||
import org.hibernate.persister.internal.PersisterClassResolverInitiator;
|
import org.hibernate.persister.internal.PersisterClassResolverInitiator;
|
||||||
import org.hibernate.persister.spi.PersisterClassResolver;
|
import org.hibernate.persister.spi.PersisterClassResolver;
|
||||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||||
@ -729,6 +730,11 @@ public boolean canUseReferenceCacheEntries() {
|
|||||||
return false; //To change body of implemented methods use File | Settings | File Templates.
|
return false; //To change body of implemented methods use File | Settings | File Templates.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<UniqueKeyEntry> uniqueKeyEntries() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SharedSessionContractImplementor session) {
|
public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SharedSessionContractImplementor session) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||||
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
|
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.entity.UniqueKeyEntry;
|
||||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||||
@ -849,6 +850,11 @@ public boolean canUseReferenceCacheEntries() {
|
|||||||
return false; //To change body of implemented methods use File | Settings | File Templates.
|
return false; //To change body of implemented methods use File | Settings | File Templates.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<UniqueKeyEntry> uniqueKeyEntries() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAffectedByEntityGraph(LoadQueryInfluencers loadQueryInfluencers) {
|
public boolean isAffectedByEntityGraph(LoadQueryInfluencers loadQueryInfluencers) {
|
||||||
return loadQueryInfluencers.getEffectiveEntityGraph().getGraph() != null;
|
return loadQueryInfluencers.getEffectiveEntityGraph().getGraph() != null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user