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
|
||||
@SuppressWarnings( "unchecked" )
|
||||
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) {
|
||||
|
@ -165,6 +165,6 @@ class MultiIdentifierLoadAccessImpl<T> implements MultiIdentifierLoadAccess<T>,
|
|||
@Override
|
||||
@SuppressWarnings( "unchecked" )
|
||||
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.MultiIdLoadOptions;
|
||||
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.query.spi.QueryOptions;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
|
@ -59,31 +61,28 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
|||
private final EntityPersister entityDescriptor;
|
||||
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.idJdbcTypeCount = bootDescriptor.getIdentifier().getColumnSpan();
|
||||
this.sessionFactory = sessionFactory;
|
||||
|
||||
assert idJdbcTypeCount > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister getLoadable() {
|
||||
public EntityMappingType getLoadable() {
|
||||
return entityDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
|
||||
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() ) {
|
||||
return performOrderedMultiLoad( ids, session, loadOptions );
|
||||
}
|
||||
|
@ -105,7 +104,7 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
|||
final JdbcEnvironment jdbcEnvironment = sessionFactory.getJdbcServices().getJdbcEnvironment();
|
||||
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)
|
||||
? new LockOptions( LockMode.NONE )
|
||||
|
@ -158,10 +157,10 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
|||
);
|
||||
managedEntity = persistenceContextEntry.getEntity();
|
||||
|
||||
if ( managedEntity != null && !loadOptions.isReturnOfDeletedEntitiesEnabled() && !persistenceContextEntry
|
||||
.isManaged() ) {
|
||||
if ( managedEntity != null
|
||||
&& !loadOptions.isReturnOfDeletedEntitiesEnabled()
|
||||
&& !persistenceContextEntry.isManaged() ) {
|
||||
// put a null in the result
|
||||
//noinspection unchecked
|
||||
result.add( i, null );
|
||||
continue;
|
||||
}
|
||||
|
@ -177,7 +176,6 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
|||
}
|
||||
|
||||
if ( managedEntity != null ) {
|
||||
//noinspection unchecked
|
||||
result.add( i, managedEntity );
|
||||
continue;
|
||||
}
|
||||
|
@ -221,12 +219,11 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
|||
entity = null;
|
||||
}
|
||||
}
|
||||
//noinspection unchecked
|
||||
result.set( position, entity );
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return (List) result;
|
||||
return (List<T>) result;
|
||||
}
|
||||
|
||||
private List<T> loadEntitiesById(
|
||||
|
@ -236,8 +233,6 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
|||
assert idsInBatch != null;
|
||||
assert ! idsInBatch.isEmpty();
|
||||
|
||||
assert idJdbcTypeCount > 0;
|
||||
|
||||
final int numberOfIdsInBatch = idsInBatch.size();
|
||||
|
||||
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();
|
||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||
.translate( jdbcParameterBindings, QueryOptions.NONE );
|
||||
|
@ -297,7 +292,7 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
|||
subSelectFetchableKeysHandler = null;
|
||||
}
|
||||
|
||||
List<T> list = JdbcSelectExecutorStandardImpl.INSTANCE.list(
|
||||
return JdbcSelectExecutorStandardImpl.INSTANCE.list(
|
||||
jdbcSelect,
|
||||
jdbcParameterBindings,
|
||||
new ExecutionContext() {
|
||||
|
@ -336,8 +331,6 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
|||
RowTransformerPassThruImpl.instance(),
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<T> performUnorderedMultiLoad(
|
||||
|
@ -397,8 +390,9 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
|||
if ( loadOptions.isSessionCheckingEnabled() ) {
|
||||
managedEntity = persistenceContextEntry.getEntity();
|
||||
|
||||
if ( managedEntity != null && !loadOptions.isReturnOfDeletedEntitiesEnabled() && !persistenceContextEntry
|
||||
.isManaged() ) {
|
||||
if ( managedEntity != null
|
||||
&& !loadOptions.isReturnOfDeletedEntitiesEnabled()
|
||||
&& !persistenceContextEntry.isManaged() ) {
|
||||
foundAnyManagedEntities = true;
|
||||
result.add( null );
|
||||
continue;
|
||||
|
|
|
@ -90,4 +90,9 @@ public class MultiNaturalIdLoaderStandard<E> implements MultiNaturalIdLoader<E>
|
|||
|
||||
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,
|
||||
jdbcParamBindings,
|
||||
new ExecutionContext() {
|
||||
|
@ -201,7 +201,5 @@ public class MultiNaturalIdLoadingBatcher {
|
|||
RowTransformerPassThruImpl.instance(),
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,16 +9,13 @@ package org.hibernate.loader.ast.spi;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* Loader subtype for loading multiple entities by multiple identifier values.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface MultiIdEntityLoader<T> extends Loader {
|
||||
@Override
|
||||
EntityPersister getLoadable();
|
||||
|
||||
List<T> load(Object[] ids, MultiIdLoadOptions options, SharedSessionContractImplementor session);
|
||||
public interface MultiIdEntityLoader<T> extends MultiLoader<T> {
|
||||
/**
|
||||
* Load multiple entities by id. The exact result depends on the passed options.
|
||||
*/
|
||||
<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;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
||||
/**
|
||||
* Loader for entities by multiple natural-ids
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
|
|
|
@ -775,11 +775,7 @@ public abstract class AbstractEntityPersister
|
|||
singleIdEntityLoader = new SingleIdEntityLoaderStandardImpl<>( this, factory );
|
||||
}
|
||||
|
||||
// todo (6.0) : allow a "max entities" to be passed (or determine based on Dialect?) indicating how many entities
|
||||
// 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 );
|
||||
multiIdEntityLoader = new MultiIdLoaderStandard<>( this, bootDescriptor, factory );
|
||||
|
||||
Iterator<Selectable> idColumns = bootDescriptor.getIdentifier().getColumnIterator();
|
||||
int i = 0;
|
||||
|
@ -4271,7 +4267,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -218,6 +218,18 @@ public interface EntityPersister
|
|||
*/
|
||||
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
|
||||
* this entity are persisted, for instances of this class and its subclasses.
|
||||
|
@ -500,7 +512,7 @@ public interface EntityPersister
|
|||
*
|
||||
* @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)
|
||||
|
|
|
@ -14,8 +14,10 @@ import org.hibernate.MappingException;
|
|||
import org.hibernate.cache.spi.access.CollectionDataAccess;
|
||||
import org.hibernate.cache.spi.access.EntityDataAccess;
|
||||
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
|
||||
import org.hibernate.internal.log.DeprecationLogger;
|
||||
import org.hibernate.mapping.Collection;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.spi.PersisterClassResolver;
|
||||
|
@ -31,49 +33,45 @@ import org.hibernate.service.spi.ServiceRegistryImplementor;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "deprecation"})
|
||||
public static final Class[] ENTITY_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public static final Class<?>[] ENTITY_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
|
||||
PersistentClass.class,
|
||||
EntityDataAccess.class,
|
||||
NaturalIdDataAccess.class,
|
||||
PersisterCreationContext.class
|
||||
RuntimeModelCreationContext.class
|
||||
};
|
||||
|
||||
/**
|
||||
* The constructor signature for {@link CollectionPersister} implementations
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "deprecation"})
|
||||
public static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public static final Class<?>[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
|
||||
Collection.class,
|
||||
CollectionDataAccess.class,
|
||||
PersisterCreationContext.class
|
||||
RuntimeModelCreationContext.class
|
||||
};
|
||||
|
||||
private ServiceRegistryImplementor serviceRegistry;
|
||||
private PersisterClassResolver persisterClassResolver;
|
||||
|
||||
@Override
|
||||
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
this.persisterClassResolver = serviceRegistry.getService( PersisterClassResolver.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public EntityPersister createEntityPersister(
|
||||
PersistentClass entityBinding,
|
||||
EntityDataAccess entityCacheAccessStrategy,
|
||||
NaturalIdDataAccess naturalIdCacheAccessStrategy,
|
||||
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) throws HibernateException {
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
// If the metadata for the entity specified an explicit persister class, use it...
|
||||
Class<? extends EntityPersister> persisterClass = entityBinding.getEntityPersisterClass();
|
||||
if ( persisterClass == null ) {
|
||||
// Otherwise, use the persister class indicated by the PersisterClassResolver service
|
||||
persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getEntityPersisterClass( entityBinding );
|
||||
persisterClass = persisterClassResolver.getEntityPersisterClass( entityBinding );
|
||||
}
|
||||
|
||||
return createEntityPersister(
|
||||
|
@ -90,39 +88,58 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
|
|||
PersistentClass entityBinding,
|
||||
EntityDataAccess entityCacheAccessStrategy,
|
||||
NaturalIdDataAccess naturalIdCacheAccessStrategy,
|
||||
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) {
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
final Constructor<? extends EntityPersister> constructor = resolveEntityPersisterConstructor( persisterClass );
|
||||
try {
|
||||
final Constructor<? extends EntityPersister> constructor = persisterClass.getConstructor( ENTITY_PERSISTER_CONSTRUCTOR_ARGS );
|
||||
try {
|
||||
return constructor.newInstance(
|
||||
entityBinding,
|
||||
entityCacheAccessStrategy,
|
||||
naturalIdCacheAccessStrategy,
|
||||
creationContext
|
||||
);
|
||||
}
|
||||
catch (MappingException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
Throwable target = e.getTargetException();
|
||||
if ( target instanceof HibernateException ) {
|
||||
throw (HibernateException) target;
|
||||
}
|
||||
else {
|
||||
throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), target );
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
|
||||
}
|
||||
return constructor.newInstance( entityBinding, entityCacheAccessStrategy, naturalIdCacheAccessStrategy, creationContext );
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
catch (MappingException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
|
||||
catch (InvocationTargetException e) {
|
||||
final Throwable target = e.getTargetException();
|
||||
if ( target instanceof HibernateException ) {
|
||||
throw (HibernateException) target;
|
||||
}
|
||||
else {
|
||||
throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), target );
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
|
||||
}
|
||||
}
|
||||
|
||||
private Constructor<? extends EntityPersister> resolveEntityPersisterConstructor(Class<? extends EntityPersister> persisterClass) {
|
||||
try {
|
||||
return persisterClass.getConstructor( ENTITY_PERSISTER_CONSTRUCTOR_ARGS );
|
||||
}
|
||||
catch (NoSuchMethodException noConstructorException) {
|
||||
// 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
|
||||
|
@ -130,14 +147,14 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
|
|||
public CollectionPersister createCollectionPersister(
|
||||
Collection collectionBinding,
|
||||
CollectionDataAccess cacheAccessStrategy,
|
||||
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) throws HibernateException {
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
// If the metadata for the collection specified an explicit persister class, use it
|
||||
Class<? extends CollectionPersister> persisterClass = collectionBinding.getCollectionPersisterClass();
|
||||
if ( persisterClass == null ) {
|
||||
// Otherwise, use the persister class indicated by the PersisterClassResolver service
|
||||
persisterClass = serviceRegistry.getService( PersisterClassResolver.class )
|
||||
.getCollectionPersisterClass( collectionBinding );
|
||||
persisterClass = persisterClassResolver.getCollectionPersisterClass( collectionBinding );
|
||||
}
|
||||
|
||||
return createCollectionPersister( persisterClass, collectionBinding, cacheAccessStrategy, creationContext );
|
||||
}
|
||||
|
||||
|
@ -146,43 +163,123 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
|
|||
Collection collectionBinding,
|
||||
CollectionDataAccess cacheAccessStrategy,
|
||||
@SuppressWarnings("deprecation") PersisterCreationContext creationContext) {
|
||||
final Constructor<? extends CollectionPersister> constructor = resolveCollectionPersisterConstructor( persisterClass );
|
||||
try {
|
||||
Constructor<? extends CollectionPersister> constructor = persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS );
|
||||
try {
|
||||
return constructor.newInstance(
|
||||
collectionBinding,
|
||||
cacheAccessStrategy,
|
||||
creationContext
|
||||
);
|
||||
}
|
||||
catch (MappingException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
Throwable target = e.getTargetException();
|
||||
if ( target instanceof HibernateException ) {
|
||||
throw (HibernateException) target;
|
||||
}
|
||||
else {
|
||||
throw new MappingException(
|
||||
String.format(
|
||||
"Could not instantiate collection persister implementor `%s` for collection-role `%s`",
|
||||
persisterClass.getName(),
|
||||
collectionBinding.getRole()
|
||||
),
|
||||
target
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
|
||||
}
|
||||
return constructor.newInstance( collectionBinding, cacheAccessStrategy, creationContext );
|
||||
}
|
||||
catch (MappingException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
Throwable target = e.getTargetException();
|
||||
if ( target instanceof HibernateException ) {
|
||||
throw (HibernateException) target;
|
||||
}
|
||||
else {
|
||||
throw new MappingException(
|
||||
String.format(
|
||||
"Could not instantiate collection persister implementor `%s` for collection-role `%s`",
|
||||
persisterClass.getName(),
|
||||
collectionBinding.getRole()
|
||||
),
|
||||
target
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
|
||||
throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
|
||||
}
|
||||
}
|
||||
|
||||
private Constructor<? extends CollectionPersister> resolveCollectionPersisterConstructor(Class<? extends CollectionPersister> persisterClass) {
|
||||
try {
|
||||
return persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS );
|
||||
}
|
||||
catch (NoSuchMethodException noConstructorException) {
|
||||
// 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.mapping.Collection;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.service.Service;
|
||||
|
@ -22,6 +23,43 @@ import org.hibernate.service.Service;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -32,8 +70,10 @@ public interface PersisterFactory extends Service {
|
|||
*
|
||||
* @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(
|
||||
PersistentClass entityBinding,
|
||||
EntityDataAccess entityCacheAccessStrategy,
|
||||
|
@ -47,13 +87,12 @@ public interface PersisterFactory extends Service {
|
|||
* @param cacheAccessStrategy The cache access strategy for the collection region
|
||||
* @param creationContext Access to additional information needed to create an EntityPersister
|
||||
*
|
||||
* @return An appropriate collection persister instance.
|
||||
*
|
||||
* @throws HibernateException Indicates a problem building the persister.
|
||||
* @deprecated (since 6.0) use {@link #createCollectionPersister(Collection, CollectionDataAccess, RuntimeModelCreationContext)}
|
||||
* instead
|
||||
*/
|
||||
@Deprecated
|
||||
CollectionPersister createCollectionPersister(
|
||||
Collection collectionBinding,
|
||||
CollectionDataAccess cacheAccessStrategy,
|
||||
PersisterCreationContext creationContext) throws HibernateException;
|
||||
|
||||
PersisterCreationContext creationContext);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue