Misc cleanup related to `MultiLoader` hierarchy
This commit is contained in:
parent
8fef9c4de4
commit
bd784b6e90
|
@ -122,7 +122,7 @@ class MultiIdentifierLoadAccessImpl<T> implements MultiIdentifierLoadAccess<T>,
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings( "unchecked" )
|
||||||
public <K> List<T> multiLoad(K... ids) {
|
public <K> List<T> multiLoad(K... ids) {
|
||||||
return perform( () -> entityPersister.multiLoad( ids, session, this ) );
|
return perform( () -> (List<T>) entityPersister.multiLoad( ids, session, this ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<T> perform(Supplier<List<T>> executor) {
|
public List<T> perform(Supplier<List<T>> executor) {
|
||||||
|
@ -165,6 +165,6 @@ class MultiIdentifierLoadAccessImpl<T> implements MultiIdentifierLoadAccess<T>,
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings( "unchecked" )
|
||||||
public <K> List<T> multiLoad(List<K> ids) {
|
public <K> List<T> multiLoad(List<K> ids) {
|
||||||
return perform( () -> entityPersister.multiLoad( ids.toArray( new Object[ 0 ] ), session, this ) );
|
return perform( () -> (List<T>) entityPersister.multiLoad( ids.toArray( new Object[ 0 ] ), session, this ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.loader.ast.spi.MultiIdEntityLoader;
|
import org.hibernate.loader.ast.spi.MultiIdEntityLoader;
|
||||||
import org.hibernate.loader.ast.spi.MultiIdLoadOptions;
|
import org.hibernate.loader.ast.spi.MultiIdLoadOptions;
|
||||||
import org.hibernate.loader.entity.CacheEntityLoaderHelper;
|
import org.hibernate.loader.entity.CacheEntityLoaderHelper;
|
||||||
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.query.spi.QueryOptions;
|
import org.hibernate.query.spi.QueryOptions;
|
||||||
import org.hibernate.query.spi.QueryParameterBindings;
|
import org.hibernate.query.spi.QueryParameterBindings;
|
||||||
|
@ -59,31 +61,28 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
private final EntityPersister entityDescriptor;
|
private final EntityPersister entityDescriptor;
|
||||||
private final SessionFactoryImplementor sessionFactory;
|
private final SessionFactoryImplementor sessionFactory;
|
||||||
|
|
||||||
private int idJdbcTypeCount = -1;
|
private final int idJdbcTypeCount;
|
||||||
|
|
||||||
public MultiIdLoaderStandard(EntityPersister entityDescriptor, SessionFactoryImplementor sessionFactory) {
|
public MultiIdLoaderStandard(
|
||||||
|
EntityPersister entityDescriptor,
|
||||||
|
PersistentClass bootDescriptor,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
this.entityDescriptor = entityDescriptor;
|
this.entityDescriptor = entityDescriptor;
|
||||||
|
this.idJdbcTypeCount = bootDescriptor.getIdentifier().getColumnSpan();
|
||||||
this.sessionFactory = sessionFactory;
|
this.sessionFactory = sessionFactory;
|
||||||
|
|
||||||
|
assert idJdbcTypeCount > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityPersister getLoadable() {
|
public EntityMappingType getLoadable() {
|
||||||
return entityDescriptor;
|
return entityDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<T> load(Object[] ids, MultiIdLoadOptions loadOptions, SharedSessionContractImplementor session) {
|
public List<T> load(Object[] ids, MultiIdLoadOptions loadOptions, SharedSessionContractImplementor session) {
|
||||||
// todo (6.0) : account for all of the `loadOptions` for now just do a simple load
|
|
||||||
// ^^ atm this is handled in `MultiIdentifierLoadAccess`. Need to decide on the design we want here...
|
|
||||||
// - see `SimpleNaturalIdMultiLoadAccessImpl` for example of alternative
|
|
||||||
|
|
||||||
assert ids != null;
|
assert ids != null;
|
||||||
|
|
||||||
if ( idJdbcTypeCount < 0 ) {
|
|
||||||
// can't do this in the ctor because of chicken-egg between this ctor and the persisters
|
|
||||||
idJdbcTypeCount = entityDescriptor.getIdentifierMapping().getJdbcTypeCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( loadOptions.isOrderReturnEnabled() ) {
|
if ( loadOptions.isOrderReturnEnabled() ) {
|
||||||
return performOrderedMultiLoad( ids, session, loadOptions );
|
return performOrderedMultiLoad( ids, session, loadOptions );
|
||||||
}
|
}
|
||||||
|
@ -105,7 +104,7 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
final JdbcEnvironment jdbcEnvironment = sessionFactory.getJdbcServices().getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = sessionFactory.getJdbcServices().getJdbcEnvironment();
|
||||||
final Dialect dialect = jdbcEnvironment.getDialect();
|
final Dialect dialect = jdbcEnvironment.getDialect();
|
||||||
|
|
||||||
final List result = CollectionHelper.arrayList( ids.length );
|
final List<Object> result = CollectionHelper.arrayList( ids.length );
|
||||||
|
|
||||||
final LockOptions lockOptions = (loadOptions.getLockOptions() == null)
|
final LockOptions lockOptions = (loadOptions.getLockOptions() == null)
|
||||||
? new LockOptions( LockMode.NONE )
|
? new LockOptions( LockMode.NONE )
|
||||||
|
@ -158,10 +157,10 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
);
|
);
|
||||||
managedEntity = persistenceContextEntry.getEntity();
|
managedEntity = persistenceContextEntry.getEntity();
|
||||||
|
|
||||||
if ( managedEntity != null && !loadOptions.isReturnOfDeletedEntitiesEnabled() && !persistenceContextEntry
|
if ( managedEntity != null
|
||||||
.isManaged() ) {
|
&& !loadOptions.isReturnOfDeletedEntitiesEnabled()
|
||||||
|
&& !persistenceContextEntry.isManaged() ) {
|
||||||
// put a null in the result
|
// put a null in the result
|
||||||
//noinspection unchecked
|
|
||||||
result.add( i, null );
|
result.add( i, null );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -177,7 +176,6 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( managedEntity != null ) {
|
if ( managedEntity != null ) {
|
||||||
//noinspection unchecked
|
|
||||||
result.add( i, managedEntity );
|
result.add( i, managedEntity );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -221,12 +219,11 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
entity = null;
|
entity = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//noinspection unchecked
|
|
||||||
result.set( position, entity );
|
result.set( position, entity );
|
||||||
}
|
}
|
||||||
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (List) result;
|
return (List<T>) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<T> loadEntitiesById(
|
private List<T> loadEntitiesById(
|
||||||
|
@ -236,8 +233,6 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
assert idsInBatch != null;
|
assert idsInBatch != null;
|
||||||
assert ! idsInBatch.isEmpty();
|
assert ! idsInBatch.isEmpty();
|
||||||
|
|
||||||
assert idJdbcTypeCount > 0;
|
|
||||||
|
|
||||||
final int numberOfIdsInBatch = idsInBatch.size();
|
final int numberOfIdsInBatch = idsInBatch.size();
|
||||||
|
|
||||||
if ( log.isTraceEnabled() ) {
|
if ( log.isTraceEnabled() ) {
|
||||||
|
@ -279,7 +274,7 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should have used all of the JdbcParameter references (created bindings for all)
|
// we should have used all the JdbcParameter references (created bindings for all)
|
||||||
assert offset == jdbcParameters.size();
|
assert offset == jdbcParameters.size();
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||||
.translate( jdbcParameterBindings, QueryOptions.NONE );
|
.translate( jdbcParameterBindings, QueryOptions.NONE );
|
||||||
|
@ -297,7 +292,7 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
subSelectFetchableKeysHandler = null;
|
subSelectFetchableKeysHandler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<T> list = JdbcSelectExecutorStandardImpl.INSTANCE.list(
|
return JdbcSelectExecutorStandardImpl.INSTANCE.list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
jdbcParameterBindings,
|
jdbcParameterBindings,
|
||||||
new ExecutionContext() {
|
new ExecutionContext() {
|
||||||
|
@ -336,8 +331,6 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
RowTransformerPassThruImpl.instance(),
|
RowTransformerPassThruImpl.instance(),
|
||||||
ListResultsConsumer.UniqueSemantic.FILTER
|
ListResultsConsumer.UniqueSemantic.FILTER
|
||||||
);
|
);
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<T> performUnorderedMultiLoad(
|
private List<T> performUnorderedMultiLoad(
|
||||||
|
@ -397,8 +390,9 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
if ( loadOptions.isSessionCheckingEnabled() ) {
|
if ( loadOptions.isSessionCheckingEnabled() ) {
|
||||||
managedEntity = persistenceContextEntry.getEntity();
|
managedEntity = persistenceContextEntry.getEntity();
|
||||||
|
|
||||||
if ( managedEntity != null && !loadOptions.isReturnOfDeletedEntitiesEnabled() && !persistenceContextEntry
|
if ( managedEntity != null
|
||||||
.isManaged() ) {
|
&& !loadOptions.isReturnOfDeletedEntitiesEnabled()
|
||||||
|
&& !persistenceContextEntry.isManaged() ) {
|
||||||
foundAnyManagedEntities = true;
|
foundAnyManagedEntities = true;
|
||||||
result.add( null );
|
result.add( null );
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -90,4 +90,9 @@ public class MultiNaturalIdLoaderStandard<E> implements MultiNaturalIdLoader<E>
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityMappingType getLoadable() {
|
||||||
|
return entityDescriptor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ public class MultiNaturalIdLoadingBatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final List<E> result = JdbcSelectExecutorStandardImpl.INSTANCE.list(
|
return JdbcSelectExecutorStandardImpl.INSTANCE.list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
jdbcParamBindings,
|
jdbcParamBindings,
|
||||||
new ExecutionContext() {
|
new ExecutionContext() {
|
||||||
|
@ -201,7 +201,5 @@ public class MultiNaturalIdLoadingBatcher {
|
||||||
RowTransformerPassThruImpl.instance(),
|
RowTransformerPassThruImpl.instance(),
|
||||||
ListResultsConsumer.UniqueSemantic.FILTER
|
ListResultsConsumer.UniqueSemantic.FILTER
|
||||||
);
|
);
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,16 +9,13 @@ package org.hibernate.loader.ast.spi;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loader subtype for loading multiple entities by multiple identifier values.
|
* Loader subtype for loading multiple entities by multiple identifier values.
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
*/
|
||||||
public interface MultiIdEntityLoader<T> extends Loader {
|
public interface MultiIdEntityLoader<T> extends MultiLoader<T> {
|
||||||
@Override
|
/**
|
||||||
EntityPersister getLoadable();
|
* Load multiple entities by id. The exact result depends on the passed options.
|
||||||
|
*/
|
||||||
List<T> load(Object[] ids, MultiIdLoadOptions options, SharedSessionContractImplementor session);
|
<K> List<T> load(K[] ids, MultiIdLoadOptions options, SharedSessionContractImplementor session);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* 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.loader.ast.spi;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commonality for multi-loading
|
||||||
|
*
|
||||||
|
* @param <T> The loaded model part
|
||||||
|
*/
|
||||||
|
public interface MultiLoader<T> extends Loader {
|
||||||
|
@Override
|
||||||
|
EntityMappingType getLoadable();
|
||||||
|
}
|
|
@ -7,18 +7,15 @@
|
||||||
package org.hibernate.loader.ast.spi;
|
package org.hibernate.loader.ast.spi;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loader for entities by multiple natural-ids
|
* Loader for entities by multiple natural-ids
|
||||||
*
|
*
|
||||||
* @param <E> The entity Java type
|
* @param <E> The entity Java type
|
||||||
*/
|
*/
|
||||||
public interface MultiNaturalIdLoader<E> {
|
public interface MultiNaturalIdLoader<E> extends MultiLoader<E> {
|
||||||
/**
|
/**
|
||||||
* Load multiple entities by natural-id. The exact result depends on the passed options.
|
* Load multiple entities by natural-id. The exact result depends on the passed options.
|
||||||
*
|
*
|
||||||
|
|
|
@ -775,11 +775,7 @@ public abstract class AbstractEntityPersister
|
||||||
singleIdEntityLoader = new SingleIdEntityLoaderStandardImpl<>( this, factory );
|
singleIdEntityLoader = new SingleIdEntityLoaderStandardImpl<>( this, factory );
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo (6.0) : allow a "max entities" to be passed (or determine based on Dialect?) indicating how many entities
|
multiIdEntityLoader = new MultiIdLoaderStandard<>( this, bootDescriptor, factory );
|
||||||
// to load at once. i.e. it limits the number of the generated IN-list JDBC-parameters in a given
|
|
||||||
// PreparedStatement, opting to split the load into multiple JDBC operations to work around database
|
|
||||||
// limits on number of parameters, number of IN-list values, etc
|
|
||||||
multiIdEntityLoader = new MultiIdLoaderStandard<>( this, factory );
|
|
||||||
|
|
||||||
Iterator<Selectable> idColumns = bootDescriptor.getIdentifier().getColumnIterator();
|
Iterator<Selectable> idColumns = bootDescriptor.getIdentifier().getColumnIterator();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -4271,7 +4267,7 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List multiLoad(Object[] ids, SharedSessionContractImplementor session, MultiIdLoadOptions loadOptions) {
|
public List<?> multiLoad(Object[] ids, SharedSessionContractImplementor session, MultiIdLoadOptions loadOptions) {
|
||||||
return multiIdEntityLoader.load( ids, loadOptions, session );
|
return multiIdEntityLoader.load( ids, loadOptions, session );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,6 +218,18 @@ public interface EntityPersister
|
||||||
*/
|
*/
|
||||||
Serializable[] getQuerySpaces();
|
Serializable[] getQuerySpaces();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The table names this entity needs to be synchronized against.
|
||||||
|
* <p>
|
||||||
|
* Much like {@link #getPropertySpaces()}, except that here we include subclass
|
||||||
|
* entity spaces.
|
||||||
|
*
|
||||||
|
* @return The synchronization spaces.
|
||||||
|
*/
|
||||||
|
default String[] getSynchronizationSpaces() {
|
||||||
|
return (String[]) getQuerySpaces();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of objects that identify spaces in which properties of
|
* Returns an array of objects that identify spaces in which properties of
|
||||||
* this entity are persisted, for instances of this class and its subclasses.
|
* this entity are persisted, for instances of this class and its subclasses.
|
||||||
|
@ -500,7 +512,7 @@ public interface EntityPersister
|
||||||
*
|
*
|
||||||
* @return The loaded, matching entities
|
* @return The loaded, matching entities
|
||||||
*/
|
*/
|
||||||
List multiLoad(Object[] ids, SharedSessionContractImplementor session, MultiIdLoadOptions loadOptions);
|
List<?> multiLoad(Object[] ids, SharedSessionContractImplementor session, MultiIdLoadOptions loadOptions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do a version check (optional operation)
|
* Do a version check (optional operation)
|
||||||
|
|
|
@ -14,8 +14,10 @@ import org.hibernate.MappingException;
|
||||||
import org.hibernate.cache.spi.access.CollectionDataAccess;
|
import org.hibernate.cache.spi.access.CollectionDataAccess;
|
||||||
import org.hibernate.cache.spi.access.EntityDataAccess;
|
import org.hibernate.cache.spi.access.EntityDataAccess;
|
||||||
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
||||||
|
import org.hibernate.internal.log.DeprecationLogger;
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
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.spi.PersisterClassResolver;
|
import org.hibernate.persister.spi.PersisterClassResolver;
|
||||||
|
@ -31,49 +33,45 @@ import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegistryAwareService {
|
public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegistryAwareService {
|
||||||
|
|
||||||
// todo : carry the notion of the creational parameters (parameter object) over to the persister constructors?
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor signature for {@link EntityPersister} implementations
|
* The constructor signature for {@link EntityPersister} implementations
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"WeakerAccess", "deprecation"})
|
@SuppressWarnings("WeakerAccess")
|
||||||
public static final Class[] ENTITY_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
|
public static final Class<?>[] ENTITY_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
|
||||||
PersistentClass.class,
|
PersistentClass.class,
|
||||||
EntityDataAccess.class,
|
EntityDataAccess.class,
|
||||||
NaturalIdDataAccess.class,
|
NaturalIdDataAccess.class,
|
||||||
PersisterCreationContext.class
|
RuntimeModelCreationContext.class
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor signature for {@link CollectionPersister} implementations
|
* The constructor signature for {@link CollectionPersister} implementations
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"WeakerAccess", "deprecation"})
|
@SuppressWarnings("WeakerAccess")
|
||||||
public static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
|
public static final Class<?>[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
|
||||||
Collection.class,
|
Collection.class,
|
||||||
CollectionDataAccess.class,
|
CollectionDataAccess.class,
|
||||||
PersisterCreationContext.class
|
RuntimeModelCreationContext.class
|
||||||
};
|
};
|
||||||
|
|
||||||
private ServiceRegistryImplementor serviceRegistry;
|
private PersisterClassResolver persisterClassResolver;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
||||||
this.serviceRegistry = serviceRegistry;
|
this.persisterClassResolver = serviceRegistry.getService( PersisterClassResolver.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings( {"unchecked"})
|
|
||||||
public EntityPersister createEntityPersister(
|
public EntityPersister createEntityPersister(
|
||||||
PersistentClass entityBinding,
|
PersistentClass entityBinding,
|
||||||
EntityDataAccess entityCacheAccessStrategy,
|
EntityDataAccess entityCacheAccessStrategy,
|
||||||
NaturalIdDataAccess naturalIdCacheAccessStrategy,
|
NaturalIdDataAccess naturalIdCacheAccessStrategy,
|
||||||
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) throws HibernateException {
|
RuntimeModelCreationContext creationContext) {
|
||||||
// If the metadata for the entity specified an explicit persister class, use it...
|
// If the metadata for the entity specified an explicit persister class, use it...
|
||||||
Class<? extends EntityPersister> persisterClass = entityBinding.getEntityPersisterClass();
|
Class<? extends EntityPersister> persisterClass = entityBinding.getEntityPersisterClass();
|
||||||
if ( persisterClass == null ) {
|
if ( persisterClass == null ) {
|
||||||
// Otherwise, use the persister class indicated by the PersisterClassResolver service
|
// Otherwise, use the persister class indicated by the PersisterClassResolver service
|
||||||
persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getEntityPersisterClass( entityBinding );
|
persisterClass = persisterClassResolver.getEntityPersisterClass( entityBinding );
|
||||||
}
|
}
|
||||||
|
|
||||||
return createEntityPersister(
|
return createEntityPersister(
|
||||||
|
@ -90,22 +88,16 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
|
||||||
PersistentClass entityBinding,
|
PersistentClass entityBinding,
|
||||||
EntityDataAccess entityCacheAccessStrategy,
|
EntityDataAccess entityCacheAccessStrategy,
|
||||||
NaturalIdDataAccess naturalIdCacheAccessStrategy,
|
NaturalIdDataAccess naturalIdCacheAccessStrategy,
|
||||||
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) {
|
RuntimeModelCreationContext creationContext) {
|
||||||
|
final Constructor<? extends EntityPersister> constructor = resolveEntityPersisterConstructor( persisterClass );
|
||||||
try {
|
try {
|
||||||
final Constructor<? extends EntityPersister> constructor = persisterClass.getConstructor( ENTITY_PERSISTER_CONSTRUCTOR_ARGS );
|
return constructor.newInstance( entityBinding, entityCacheAccessStrategy, naturalIdCacheAccessStrategy, creationContext );
|
||||||
try {
|
|
||||||
return constructor.newInstance(
|
|
||||||
entityBinding,
|
|
||||||
entityCacheAccessStrategy,
|
|
||||||
naturalIdCacheAccessStrategy,
|
|
||||||
creationContext
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
catch (MappingException e) {
|
catch (MappingException e) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
Throwable target = e.getTargetException();
|
final Throwable target = e.getTargetException();
|
||||||
if ( target instanceof HibernateException ) {
|
if ( target instanceof HibernateException ) {
|
||||||
throw (HibernateException) target;
|
throw (HibernateException) target;
|
||||||
}
|
}
|
||||||
|
@ -117,12 +109,37 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
|
||||||
throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
|
throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (HibernateException e) {
|
|
||||||
throw e;
|
private Constructor<? extends EntityPersister> resolveEntityPersisterConstructor(Class<? extends EntityPersister> persisterClass) {
|
||||||
|
try {
|
||||||
|
return persisterClass.getConstructor( ENTITY_PERSISTER_CONSTRUCTOR_ARGS );
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (NoSuchMethodException noConstructorException) {
|
||||||
throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
|
// we could not find the constructor...
|
||||||
|
//
|
||||||
|
// until we drop support for the legacy constructor signature, see if they define a
|
||||||
|
// constructor using that signature and use it if so
|
||||||
|
try {
|
||||||
|
final Constructor<? extends EntityPersister> constructor = persisterClass.getConstructor( LEGACY_ENTITY_PERSISTER_CONSTRUCTOR_ARGS );
|
||||||
|
// they do use the legacy signature...
|
||||||
|
|
||||||
|
// warn them
|
||||||
|
DeprecationLogger.DEPRECATION_LOGGER.debugf(
|
||||||
|
"EntityPersister implementation defined constructor using legacy signature using `%s`; use `%s` instead",
|
||||||
|
PersisterCreationContext.class.getName(),
|
||||||
|
RuntimeModelCreationContext.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
// but use it
|
||||||
|
return constructor;
|
||||||
}
|
}
|
||||||
|
catch (NoSuchMethodException noLegacyConstructorException) {
|
||||||
|
// fall through to below
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new MappingException( "Could not find appropriate constructor for " + persisterClass.getName(), noConstructorException );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -130,14 +147,14 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
|
||||||
public CollectionPersister createCollectionPersister(
|
public CollectionPersister createCollectionPersister(
|
||||||
Collection collectionBinding,
|
Collection collectionBinding,
|
||||||
CollectionDataAccess cacheAccessStrategy,
|
CollectionDataAccess cacheAccessStrategy,
|
||||||
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) throws HibernateException {
|
RuntimeModelCreationContext creationContext) {
|
||||||
// If the metadata for the collection specified an explicit persister class, use it
|
// If the metadata for the collection specified an explicit persister class, use it
|
||||||
Class<? extends CollectionPersister> persisterClass = collectionBinding.getCollectionPersisterClass();
|
Class<? extends CollectionPersister> persisterClass = collectionBinding.getCollectionPersisterClass();
|
||||||
if ( persisterClass == null ) {
|
if ( persisterClass == null ) {
|
||||||
// Otherwise, use the persister class indicated by the PersisterClassResolver service
|
// Otherwise, use the persister class indicated by the PersisterClassResolver service
|
||||||
persisterClass = serviceRegistry.getService( PersisterClassResolver.class )
|
persisterClass = persisterClassResolver.getCollectionPersisterClass( collectionBinding );
|
||||||
.getCollectionPersisterClass( collectionBinding );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return createCollectionPersister( persisterClass, collectionBinding, cacheAccessStrategy, creationContext );
|
return createCollectionPersister( persisterClass, collectionBinding, cacheAccessStrategy, creationContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,14 +163,9 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
|
||||||
Collection collectionBinding,
|
Collection collectionBinding,
|
||||||
CollectionDataAccess cacheAccessStrategy,
|
CollectionDataAccess cacheAccessStrategy,
|
||||||
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) {
|
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) {
|
||||||
|
final Constructor<? extends CollectionPersister> constructor = resolveCollectionPersisterConstructor( persisterClass );
|
||||||
try {
|
try {
|
||||||
Constructor<? extends CollectionPersister> constructor = persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS );
|
return constructor.newInstance( collectionBinding, cacheAccessStrategy, creationContext );
|
||||||
try {
|
|
||||||
return constructor.newInstance(
|
|
||||||
collectionBinding,
|
|
||||||
cacheAccessStrategy,
|
|
||||||
creationContext
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
catch (MappingException e) {
|
catch (MappingException e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -178,11 +190,96 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
|
||||||
throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
|
throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (MappingException e) {
|
|
||||||
throw e;
|
private Constructor<? extends CollectionPersister> resolveCollectionPersisterConstructor(Class<? extends CollectionPersister> persisterClass) {
|
||||||
|
try {
|
||||||
|
return persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS );
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (NoSuchMethodException noConstructorException) {
|
||||||
throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
|
// we could not find the constructor...
|
||||||
|
//
|
||||||
|
// until we drop support for the legacy constructor signature, see if they define a
|
||||||
|
// constructor using that signature and use it if so
|
||||||
|
try {
|
||||||
|
final Constructor<? extends CollectionPersister> constructor = persisterClass.getConstructor( LEGACY_COLLECTION_PERSISTER_CONSTRUCTOR_ARGS );
|
||||||
|
// they do use the legacy signature...
|
||||||
|
|
||||||
|
// warn them
|
||||||
|
DeprecationLogger.DEPRECATION_LOGGER.debugf(
|
||||||
|
"CollectionPersister implementation defined constructor using legacy signature using `%s`; use `%s` instead",
|
||||||
|
PersisterCreationContext.class.getName(),
|
||||||
|
RuntimeModelCreationContext.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
// but use it
|
||||||
|
return constructor;
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException noLegacyConstructorException) {
|
||||||
|
// fall through to below
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new MappingException( "Could not find appropriate constructor for " + persisterClass.getName(), noConstructorException );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The legacy constructor signature for {@link EntityPersister} implementations
|
||||||
|
*
|
||||||
|
* @deprecated (as of 6.0) - use {@link #ENTITY_PERSISTER_CONSTRUCTOR_ARGS} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
private static final Class<?>[] LEGACY_ENTITY_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
|
||||||
|
PersistentClass.class,
|
||||||
|
EntityDataAccess.class,
|
||||||
|
NaturalIdDataAccess.class,
|
||||||
|
PersisterCreationContext.class
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityPersister createEntityPersister(
|
||||||
|
PersistentClass entityBinding,
|
||||||
|
EntityDataAccess entityCacheAccessStrategy,
|
||||||
|
NaturalIdDataAccess naturalIdCacheAccessStrategy,
|
||||||
|
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) {
|
||||||
|
DeprecationLogger.DEPRECATION_LOGGER.debugf(
|
||||||
|
"Encountered use of deprecated `PersisterFactory#createEntityPersister` form accepting `%s`; use form accepting `%s` instead",
|
||||||
|
PersisterCreationContext.class.getName(),
|
||||||
|
RuntimeModelCreationContext.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
return createEntityPersister(
|
||||||
|
entityBinding,
|
||||||
|
entityCacheAccessStrategy,
|
||||||
|
naturalIdCacheAccessStrategy,
|
||||||
|
(RuntimeModelCreationContext) creationContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constructor signature for {@link CollectionPersister} implementations
|
||||||
|
*
|
||||||
|
* @deprecated (as of 6.0) - use {@link #COLLECTION_PERSISTER_CONSTRUCTOR_ARGS} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
private static final Class<?>[] LEGACY_COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
|
||||||
|
Collection.class,
|
||||||
|
CollectionDataAccess.class,
|
||||||
|
PersisterCreationContext.class
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionPersister createCollectionPersister(
|
||||||
|
Collection collectionBinding,
|
||||||
|
CollectionDataAccess cacheAccessStrategy,
|
||||||
|
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) throws HibernateException {
|
||||||
|
DeprecationLogger.DEPRECATION_LOGGER.debugf(
|
||||||
|
"Encountered use of deprecated `PersisterFactory#createCollectionPersister` form accepting `%s`; use form accepting `%s` instead",
|
||||||
|
PersisterCreationContext.class.getName(),
|
||||||
|
RuntimeModelCreationContext.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
return createCollectionPersister( collectionBinding, cacheAccessStrategy, (RuntimeModelCreationContext) creationContext );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.cache.spi.access.EntityDataAccess;
|
||||||
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
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.service.Service;
|
import org.hibernate.service.Service;
|
||||||
|
@ -22,6 +23,43 @@ import org.hibernate.service.Service;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface PersisterFactory extends Service {
|
public interface PersisterFactory extends Service {
|
||||||
|
/**
|
||||||
|
* Create an entity persister instance.
|
||||||
|
*
|
||||||
|
* @param entityBinding The mapping information describing the entity
|
||||||
|
* @param entityCacheAccessStrategy The cache access strategy for the entity region
|
||||||
|
* @param naturalIdCacheAccessStrategy The cache access strategy for the entity's natural-id cross-ref region
|
||||||
|
* @param creationContext Access to additional information needed to create the EntityPersister
|
||||||
|
*/
|
||||||
|
default EntityPersister createEntityPersister(
|
||||||
|
PersistentClass entityBinding,
|
||||||
|
EntityDataAccess entityCacheAccessStrategy,
|
||||||
|
NaturalIdDataAccess naturalIdCacheAccessStrategy,
|
||||||
|
RuntimeModelCreationContext creationContext) {
|
||||||
|
// for now, to minimize impact on existing custom impls, default this form to delegate to the original
|
||||||
|
return createEntityPersister(
|
||||||
|
entityBinding,
|
||||||
|
entityCacheAccessStrategy,
|
||||||
|
naturalIdCacheAccessStrategy,
|
||||||
|
(PersisterCreationContext) creationContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a collection persister instance.
|
||||||
|
*
|
||||||
|
* @param collectionBinding The mapping information describing the collection
|
||||||
|
* @param cacheAccessStrategy The cache access strategy for the collection region
|
||||||
|
* @param creationContext Access to additional information needed to create an EntityPersister
|
||||||
|
*/
|
||||||
|
default CollectionPersister createCollectionPersister(
|
||||||
|
Collection collectionBinding,
|
||||||
|
CollectionDataAccess cacheAccessStrategy,
|
||||||
|
RuntimeModelCreationContext creationContext) {
|
||||||
|
// for now, to minimize impact on existing custom impls, default this form to delegate to the original
|
||||||
|
return createCollectionPersister( collectionBinding, cacheAccessStrategy, (PersisterCreationContext) creationContext );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an entity persister instance.
|
* Create an entity persister instance.
|
||||||
*
|
*
|
||||||
|
@ -32,8 +70,10 @@ public interface PersisterFactory extends Service {
|
||||||
*
|
*
|
||||||
* @return An appropriate entity persister instance.
|
* @return An appropriate entity persister instance.
|
||||||
*
|
*
|
||||||
* @throws HibernateException Indicates a problem building the persister.
|
* @deprecated (since 6.0) use {@link #createEntityPersister(PersistentClass, EntityDataAccess, NaturalIdDataAccess, RuntimeModelCreationContext)}
|
||||||
|
* instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
EntityPersister createEntityPersister(
|
EntityPersister createEntityPersister(
|
||||||
PersistentClass entityBinding,
|
PersistentClass entityBinding,
|
||||||
EntityDataAccess entityCacheAccessStrategy,
|
EntityDataAccess entityCacheAccessStrategy,
|
||||||
|
@ -47,13 +87,12 @@ public interface PersisterFactory extends Service {
|
||||||
* @param cacheAccessStrategy The cache access strategy for the collection region
|
* @param cacheAccessStrategy The cache access strategy for the collection region
|
||||||
* @param creationContext Access to additional information needed to create an EntityPersister
|
* @param creationContext Access to additional information needed to create an EntityPersister
|
||||||
*
|
*
|
||||||
* @return An appropriate collection persister instance.
|
* @deprecated (since 6.0) use {@link #createCollectionPersister(Collection, CollectionDataAccess, RuntimeModelCreationContext)}
|
||||||
*
|
* instead
|
||||||
* @throws HibernateException Indicates a problem building the persister.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
CollectionPersister createCollectionPersister(
|
CollectionPersister createCollectionPersister(
|
||||||
Collection collectionBinding,
|
Collection collectionBinding,
|
||||||
CollectionDataAccess cacheAccessStrategy,
|
CollectionDataAccess cacheAccessStrategy,
|
||||||
PersisterCreationContext creationContext) throws HibernateException;
|
PersisterCreationContext creationContext);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue