HHH-16407 - EntityPersister and CollectionPersister deprecations
This commit is contained in:
parent
6b8efd01fa
commit
7db9bc83c1
|
@ -243,7 +243,8 @@ public class PersistentBag<E> extends AbstractPersistentCollection<E> implements
|
|||
@Override
|
||||
public void initializeEmptyCollection(CollectionPersister persister) {
|
||||
assert bag == null;
|
||||
bag = (List<E>) persister.getCollectionType().instantiate( 0 );
|
||||
//noinspection unchecked
|
||||
bag = (List<E>) persister.getCollectionSemantics().instantiateRaw( 0, persister );
|
||||
endRead();
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,8 @@ public class PersistentList<E> extends AbstractPersistentCollection<E> implement
|
|||
@SuppressWarnings("unchecked")
|
||||
public void initializeEmptyCollection(CollectionPersister persister) {
|
||||
assert list == null;
|
||||
list = (List<E>) persister.getCollectionType().instantiate( 0 );
|
||||
//noinspection unchecked
|
||||
list = (List<E>) persister.getCollectionSemantics().instantiateRaw( 0, persister );
|
||||
endRead();
|
||||
}
|
||||
|
||||
|
@ -121,7 +122,7 @@ public class PersistentList<E> extends AbstractPersistentCollection<E> implement
|
|||
final int size = array.length;
|
||||
|
||||
assert list == null;
|
||||
this.list = (List<E>) persister.getCollectionType().instantiate( size );
|
||||
list = (List<E>) persister.getCollectionSemantics().instantiateRaw( size, persister );
|
||||
|
||||
for ( Serializable arrayElement : array ) {
|
||||
list.add( (E) persister.getElementType().assemble( arrayElement, getSession(), owner ) );
|
||||
|
|
|
@ -94,7 +94,8 @@ public class PersistentMap<K,E> extends AbstractPersistentCollection<E> implemen
|
|||
@Override
|
||||
public void initializeEmptyCollection(CollectionPersister persister) {
|
||||
assert map == null;
|
||||
map = (Map<K,E>) persister.getCollectionType().instantiate( 0 );
|
||||
//noinspection unchecked
|
||||
map = (Map<K,E>) persister.getCollectionSemantics().instantiateRaw( 0, persister );
|
||||
endRead();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Collection;
|
|||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -96,7 +97,8 @@ public class PersistentSet<E> extends AbstractPersistentCollection<E> implements
|
|||
@Override
|
||||
public void initializeEmptyCollection(CollectionPersister persister) {
|
||||
assert set == null;
|
||||
set = (Set<E>) persister.getCollectionType().instantiate( 0 );
|
||||
//noinspection unchecked
|
||||
set = (Set<E>) persister.getCollectionSemantics().instantiateRaw( 0, persister );
|
||||
endRead();
|
||||
}
|
||||
|
||||
|
|
|
@ -210,7 +210,6 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
sessionFactoryOptions = options;
|
||||
|
||||
serviceRegistry = getServiceRegistry( options, this );
|
||||
|
||||
eventEngine = new EventEngine( bootMetamodel, this );
|
||||
|
||||
bootMetamodel.initSessionFactory( this );
|
||||
|
@ -262,21 +261,77 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
// registry here, and doing the engine later
|
||||
queryEngine = QueryEngine.from( this, bootMetamodel );
|
||||
|
||||
// this is where creation of the runtime metamodel happens
|
||||
// create runtime metamodels (mapping and JPA)
|
||||
final RuntimeMetamodelsImpl runtimeMetamodelsImpl = new RuntimeMetamodelsImpl();
|
||||
runtimeMetamodels = runtimeMetamodelsImpl;
|
||||
new RuntimeModelCreationContext() {
|
||||
final MappingMetamodelImpl mappingMetamodelImpl =
|
||||
new MappingMetamodelImpl( typeConfiguration, serviceRegistry );
|
||||
{
|
||||
// need to set this before calling finishInitialization()
|
||||
final MappingMetamodelImpl mappingMetamodelImpl = new MappingMetamodelImpl( typeConfiguration, serviceRegistry );
|
||||
runtimeMetamodelsImpl.setMappingMetamodel( mappingMetamodelImpl );
|
||||
// because this calls back to the RuntimeMetamodelsImplementor
|
||||
mappingMetamodelImpl.finishInitialization( this );
|
||||
// need to set this after calling finishInitialization()
|
||||
initializeMappingModel( mappingMetamodelImpl, bootstrapContext, bootMetamodel, options );
|
||||
runtimeMetamodelsImpl.setJpaMetamodel( mappingMetamodelImpl.getJpaMetamodel() );
|
||||
|
||||
// this needs to happen after the mapping metamodel is
|
||||
// completely built, since we need to use the persisters
|
||||
fetchProfiles = getFetchProfiles( bootMetamodel, runtimeMetamodels.getMappingMetamodel() );
|
||||
|
||||
defaultSessionOpenOptions = createDefaultSessionOpenOptionsIfPossible();
|
||||
temporarySessionOpenOptions = defaultSessionOpenOptions == null ? null : buildTemporarySessionOpenOptions();
|
||||
defaultStatelessOptions = defaultSessionOpenOptions == null ? null : withStatelessOptions();
|
||||
fastSessionServices = new FastSessionServices( this );
|
||||
wrapperOptions = new SessionFactoryBasedWrapperOptions( this );
|
||||
|
||||
currentSessionContext = buildCurrentSessionContext();
|
||||
|
||||
// re-scope the TypeConfiguration to this SessionFactory,
|
||||
// now that we are (almost) fully-initialized ... note,
|
||||
// we could have done this earlier, but then it's hard to
|
||||
// really know or control who's calling back to us while
|
||||
// we're in an incompletely-initialized state
|
||||
typeConfiguration.scope( this );
|
||||
|
||||
observer.sessionFactoryCreated( this );
|
||||
|
||||
// As last operation, delete all caches from ReflectionManager
|
||||
// (not modelled as a listener as we want this to be last)
|
||||
bootstrapContext.getReflectionManager().reset();
|
||||
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
disintegrate( e, integratorObserver );
|
||||
|
||||
try {
|
||||
close();
|
||||
}
|
||||
catch (Exception closeException) {
|
||||
LOG.debugf( "Eating error closing the SessionFactory after a failed attempt to start it" );
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
LOG.debug( "Instantiated SessionFactory" );
|
||||
}
|
||||
|
||||
private void initializeMappingModel(
|
||||
MappingMetamodelImpl mappingMetamodelImpl,
|
||||
BootstrapContext bootstrapContext,
|
||||
MetadataImplementor bootMetamodel,
|
||||
SessionFactoryOptions options) {
|
||||
final TypeConfiguration typeConfiguration = mappingMetamodelImpl.getTypeConfiguration();
|
||||
mappingMetamodelImpl.finishInitialization( runtimeModelCreationContext(
|
||||
bootstrapContext,
|
||||
bootMetamodel,
|
||||
mappingMetamodelImpl,
|
||||
typeConfiguration,
|
||||
options
|
||||
) );
|
||||
}
|
||||
|
||||
private RuntimeModelCreationContext runtimeModelCreationContext(
|
||||
BootstrapContext bootstrapContext,
|
||||
MetadataImplementor bootMetamodel,
|
||||
MappingMetamodelImplementor mappingMetamodel,
|
||||
TypeConfiguration typeConfiguration,
|
||||
SessionFactoryOptions options) {
|
||||
return new RuntimeModelCreationContext() {
|
||||
@Override
|
||||
public BootstrapContext getBootstrapContext() {
|
||||
return bootstrapContext;
|
||||
|
@ -295,7 +350,7 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
|
||||
@Override
|
||||
public MappingMetamodelImplementor getDomainModel() {
|
||||
return mappingMetamodelImpl;
|
||||
return mappingMetamodel;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -343,46 +398,6 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
return serviceRegistry;
|
||||
}
|
||||
};
|
||||
|
||||
// this needs to happen after the mapping metamodel is
|
||||
// completely built, since we need to use the persisters
|
||||
fetchProfiles = getFetchProfiles( bootMetamodel, runtimeMetamodels.getMappingMetamodel() );
|
||||
|
||||
defaultSessionOpenOptions = createDefaultSessionOpenOptionsIfPossible();
|
||||
temporarySessionOpenOptions = defaultSessionOpenOptions == null ? null : buildTemporarySessionOpenOptions();
|
||||
defaultStatelessOptions = defaultSessionOpenOptions == null ? null : withStatelessOptions();
|
||||
fastSessionServices = new FastSessionServices( this );
|
||||
wrapperOptions = new SessionFactoryBasedWrapperOptions( this );
|
||||
|
||||
currentSessionContext = buildCurrentSessionContext();
|
||||
|
||||
// re-scope the TypeConfiguration to this SessionFactory,
|
||||
// now that we are (almost) fully-initialized ... note,
|
||||
// we could have done this earlier, but then it's hard to
|
||||
// really know or control who's calling back to us while
|
||||
// we're in an incompletely-initialized state
|
||||
typeConfiguration.scope( this );
|
||||
|
||||
observer.sessionFactoryCreated( this );
|
||||
|
||||
// As last operation, delete all caches from ReflectionManager
|
||||
// (not modelled as a listener as we want this to be last)
|
||||
bootstrapContext.getReflectionManager().reset();
|
||||
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
disintegrate( e, integratorObserver );
|
||||
|
||||
try {
|
||||
close();
|
||||
}
|
||||
catch (Exception closeException) {
|
||||
LOG.debugf( "Eating error closing the SessionFactory after a failed attempt to start it" );
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
LOG.debug( "Instantiated SessionFactory" );
|
||||
}
|
||||
|
||||
private static Map<String, Generator> createGenerators(
|
||||
|
|
|
@ -44,6 +44,20 @@ public class CollectionElementLoaderByIndex implements Loader {
|
|||
|
||||
private final int keyJdbcCount;
|
||||
|
||||
/**
|
||||
* Shortened form of {@link #CollectionElementLoaderByIndex(PluralAttributeMapping, int, LoadQueryInfluencers, SessionFactoryImplementor)}
|
||||
* which applied the collection mapping's {@linkplain PluralAttributeMapping.IndexMetadata#getListIndexBase()}
|
||||
*/
|
||||
public CollectionElementLoaderByIndex(
|
||||
PluralAttributeMapping attributeMapping,
|
||||
LoadQueryInfluencers influencers,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
this( attributeMapping, attributeMapping.getIndexMetadata().getListIndexBase(), influencers, sessionFactory );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param baseIndex A base value to apply to the relational index values processed on {@link #incrementIndexByBase}
|
||||
*/
|
||||
public CollectionElementLoaderByIndex(
|
||||
PluralAttributeMapping attributeMapping,
|
||||
int baseIndex,
|
||||
|
@ -144,11 +158,20 @@ public class CollectionElementLoaderByIndex implements Loader {
|
|||
return list.get( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* If the index being loaded by for a List and the mapping specified a
|
||||
* {@linkplain org.hibernate.annotations.ListIndexBase base-index}, this will return
|
||||
* the passed {@code index} value incremented by the base. Otherwise, the passed {@code index}
|
||||
* is returned.
|
||||
*
|
||||
* @param index The relational index value; specifically without any mapped base applied
|
||||
*
|
||||
* @return The appropriately incremented base
|
||||
*/
|
||||
protected Object incrementIndexByBase(Object index) {
|
||||
if ( baseIndex != 0 ) {
|
||||
index = (Integer) index + baseIndex;
|
||||
if ( baseIndex > 0 ) {
|
||||
return (Integer) index + baseIndex;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,30 +27,30 @@ public enum CollectionClassification {
|
|||
* An Object or primitive array. Roughly follows the semantics
|
||||
* of {@link #LIST}
|
||||
*/
|
||||
ARRAY( PluralAttribute.CollectionType.COLLECTION ),
|
||||
ARRAY( PluralAttribute.CollectionType.COLLECTION, true ),
|
||||
|
||||
/**
|
||||
* A non-unique, unordered collection. Represented
|
||||
* as {@link java.util.Collection} or {@link java.util.List}
|
||||
*/
|
||||
BAG( PluralAttribute.CollectionType.COLLECTION ),
|
||||
BAG( PluralAttribute.CollectionType.COLLECTION, false ),
|
||||
|
||||
/**
|
||||
* A {@link #BAG} with a generated id for each element
|
||||
*/
|
||||
ID_BAG( PluralAttribute.CollectionType.COLLECTION ),
|
||||
ID_BAG( PluralAttribute.CollectionType.COLLECTION, false ),
|
||||
|
||||
/**
|
||||
* A non-unique, ordered collection following the requirements of {@link java.util.List}
|
||||
*
|
||||
* @see org.hibernate.cfg.AvailableSettings#DEFAULT_LIST_SEMANTICS
|
||||
*/
|
||||
LIST( PluralAttribute.CollectionType.LIST ),
|
||||
LIST( PluralAttribute.CollectionType.LIST, true ),
|
||||
|
||||
/**
|
||||
* A unique, unordered collection following the requirements of {@link java.util.Set}
|
||||
*/
|
||||
SET( PluralAttribute.CollectionType.SET ),
|
||||
SET( PluralAttribute.CollectionType.SET, false ),
|
||||
|
||||
/**
|
||||
* A sorted {@link #SET} using either natural sorting of the elements or a
|
||||
|
@ -60,7 +60,7 @@ public enum CollectionClassification {
|
|||
* @see org.hibernate.annotations.SortNatural
|
||||
* @see org.hibernate.annotations.SortComparator
|
||||
*/
|
||||
SORTED_SET( PluralAttribute.CollectionType.SET ),
|
||||
SORTED_SET( PluralAttribute.CollectionType.SET, false ),
|
||||
|
||||
/**
|
||||
* A {@link #SET} that is ordered using an order-by fragment
|
||||
|
@ -71,12 +71,12 @@ public enum CollectionClassification {
|
|||
* @see jakarta.persistence.OrderBy
|
||||
* @see org.hibernate.annotations.OrderBy
|
||||
*/
|
||||
ORDERED_SET( PluralAttribute.CollectionType.SET ),
|
||||
ORDERED_SET( PluralAttribute.CollectionType.SET, false ),
|
||||
|
||||
/**
|
||||
* A collection following the semantics of {@link java.util.Map}
|
||||
*/
|
||||
MAP( PluralAttribute.CollectionType.MAP ),
|
||||
MAP( PluralAttribute.CollectionType.MAP, true ),
|
||||
|
||||
/**
|
||||
* A sorted {@link #MAP} using either natural sorting of the keys or a
|
||||
|
@ -86,7 +86,7 @@ public enum CollectionClassification {
|
|||
* @see org.hibernate.annotations.SortNatural
|
||||
* @see org.hibernate.annotations.SortComparator
|
||||
*/
|
||||
SORTED_MAP( PluralAttribute.CollectionType.MAP ),
|
||||
SORTED_MAP( PluralAttribute.CollectionType.MAP, true ),
|
||||
|
||||
/**
|
||||
* A {@link #MAP} that is ordered using an order-by fragment
|
||||
|
@ -97,18 +97,29 @@ public enum CollectionClassification {
|
|||
* @see jakarta.persistence.OrderBy
|
||||
* @see org.hibernate.annotations.OrderBy
|
||||
*/
|
||||
ORDERED_MAP( PluralAttribute.CollectionType.MAP );
|
||||
ORDERED_MAP( PluralAttribute.CollectionType.MAP, true );
|
||||
|
||||
private final PluralAttribute.CollectionType jpaClassification;
|
||||
private final boolean isIndexed;
|
||||
|
||||
CollectionClassification(PluralAttribute.CollectionType jpaClassification) {
|
||||
CollectionClassification(PluralAttribute.CollectionType jpaClassification, boolean isIndexed) {
|
||||
this.jpaClassification = jpaClassification;
|
||||
this.isIndexed = isIndexed;
|
||||
}
|
||||
|
||||
public PluralAttribute.CollectionType toJpaClassification() {
|
||||
return jpaClassification;
|
||||
}
|
||||
|
||||
public boolean isIndexed() {
|
||||
return isIndexed;
|
||||
}
|
||||
|
||||
public boolean isRowUpdatePossible() {
|
||||
// anything other than BAG and SET
|
||||
return this != BAG && this != SET;
|
||||
}
|
||||
|
||||
/**
|
||||
* One of:<ul>
|
||||
* <li>{@link org.hibernate.metamodel.CollectionClassification} instance</li>
|
||||
|
@ -174,9 +185,4 @@ public enum CollectionClassification {
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isRowUpdatePossible() {
|
||||
// anything other than BAG and SET
|
||||
return this != BAG && this != SET;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.Internal;
|
|||
import org.hibernate.boot.jaxb.mapping.JaxbEntity;
|
||||
import org.hibernate.engine.OptimisticLockStyle;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.loader.ast.spi.Loadable;
|
||||
import org.hibernate.loader.ast.spi.MultiNaturalIdLoader;
|
||||
import org.hibernate.loader.ast.spi.NaturalIdLoader;
|
||||
|
@ -458,6 +459,12 @@ public interface EntityMappingType
|
|||
*/
|
||||
MultiNaturalIdLoader<?> getMultiNaturalIdLoader();
|
||||
|
||||
/**
|
||||
* Load an instance of the persistent class, by a unique key other
|
||||
* than the primary key.
|
||||
*/
|
||||
Object loadByUniqueKey(String propertyName, Object uniqueKey, SharedSessionContractImplementor session);
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Loadable
|
||||
|
|
|
@ -174,6 +174,7 @@ public class PluralAttributeMappingImpl
|
|||
else {
|
||||
baseIndex = -1;
|
||||
}
|
||||
|
||||
indexMetadata = new IndexMetadata() {
|
||||
@Override
|
||||
public CollectionPart getIndexDescriptor() {
|
||||
|
|
|
@ -7,18 +7,23 @@
|
|||
package org.hibernate.metamodel.model.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.hibernate.spi.DotIdentifierSequence;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.spi.DotIdentifierSequence;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
|
||||
/**
|
||||
* Poorly named.
|
||||
* A compound path which represents a {@link org.hibernate.metamodel.mapping.ModelPart}
|
||||
* and uniquely identifies it with the runtime metamodel.
|
||||
* <p/>
|
||||
* The {@linkplain #isRoot() root} will name either an
|
||||
* {@linkplain org.hibernate.metamodel.MappingMetamodel#getEntityDescriptor entity} or
|
||||
* {@linkplain org.hibernate.metamodel.MappingMetamodel#getCollectionDescriptor collection}
|
||||
*
|
||||
* Should have been named `org.hibernate.metamodel.model.mapping.MappingRole`
|
||||
*
|
||||
* Represents a compound path of `ModelPart` nodes rooted at an entity-name.
|
||||
* @apiNote Poorly named. Should probably have been `org.hibernate.metamodel.model.mapping.MappingRole`;
|
||||
* the term "navigable" here is meant to indicate that we could navigate to the specific
|
||||
* {@link org.hibernate.metamodel.mapping.ModelPart} given the role.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.persister.collection;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
@ -70,11 +69,11 @@ import org.hibernate.mapping.Column;
|
|||
import org.hibernate.mapping.Formula;
|
||||
import org.hibernate.mapping.IdentifierCollection;
|
||||
import org.hibernate.mapping.IndexedCollection;
|
||||
import org.hibernate.mapping.List;
|
||||
import org.hibernate.mapping.Selectable;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.metadata.CollectionMetadata;
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
|
@ -146,11 +145,14 @@ import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER
|
|||
*/
|
||||
@Internal
|
||||
public abstract class AbstractCollectionPersister
|
||||
implements SQLLoadableCollection, PluralAttributeMappingImpl.Aware, CollectionMutationTarget, CollectionMetadata {
|
||||
implements CollectionPersister, CollectionMutationTarget, PluralAttributeMappingImpl.Aware, DeprecatedCollectionStuff {
|
||||
|
||||
private final NavigableRole navigableRole;
|
||||
private final CollectionSemantics<?,?> collectionSemantics;
|
||||
private final EntityPersister ownerPersister;
|
||||
private final SessionFactoryImplementor factory;
|
||||
|
||||
protected final String qualifiedTableName;
|
||||
private final CollectionTableMapping tableMapping;
|
||||
|
||||
private final String sqlSelectSizeString;
|
||||
|
@ -164,19 +166,11 @@ public abstract class AbstractCollectionPersister
|
|||
private final boolean hasOrder;
|
||||
private final boolean hasManyToManyOrder;
|
||||
|
||||
private final int baseIndex;
|
||||
|
||||
private final String mappedByProperty;
|
||||
|
||||
protected final boolean indexContainsFormula;
|
||||
protected final boolean elementIsPureFormula;
|
||||
|
||||
// types
|
||||
private final Type keyType;
|
||||
private final Type indexType;
|
||||
protected final Type elementType;
|
||||
private final Type identifierType;
|
||||
|
||||
// columns
|
||||
protected final String[] keyColumnNames;
|
||||
protected final String[] indexColumnNames;
|
||||
|
@ -192,21 +186,12 @@ public abstract class AbstractCollectionPersister
|
|||
protected final String[] elementFormulas;
|
||||
protected final boolean[] elementColumnIsGettable;
|
||||
protected final boolean[] elementColumnIsSettable;
|
||||
protected final String[] indexColumnAliases;
|
||||
protected final String[] elementColumnAliases;
|
||||
protected final String[] keyColumnAliases;
|
||||
|
||||
protected final String identifierColumnName;
|
||||
private final String identifierColumnAlias;
|
||||
|
||||
protected final String qualifiedTableName;
|
||||
|
||||
private final String queryLoaderName;
|
||||
|
||||
private final boolean isPrimitiveArray;
|
||||
private final boolean isArray;
|
||||
protected final boolean hasIndex;
|
||||
protected final boolean hasIdentifier;
|
||||
private final boolean isLazy;
|
||||
private final boolean isExtraLazy;
|
||||
protected final boolean isInverse;
|
||||
|
@ -219,17 +204,13 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
// extra information about the element type
|
||||
private final Class<?> elementClass;
|
||||
private final String entityName;
|
||||
|
||||
private final Dialect dialect;
|
||||
protected final SqlExceptionHelper sqlExceptionHelper;
|
||||
private final SessionFactoryImplementor factory;
|
||||
private final EntityPersister ownerPersister;
|
||||
private final BeforeExecutionGenerator identifierGenerator;
|
||||
private final PropertyMapping elementPropertyMapping;
|
||||
private final EntityPersister elementPersister;
|
||||
private final CollectionDataAccess cacheAccessStrategy;
|
||||
private final CollectionType collectionType;
|
||||
|
||||
private final CacheEntryStructure cacheEntryStructure;
|
||||
|
||||
|
@ -244,8 +225,6 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
private final String[] spaces;
|
||||
|
||||
private final Map<String,String[]> collectionPropertyColumnAliases = new HashMap<>();
|
||||
|
||||
private final Comparator<?> comparator;
|
||||
|
||||
private CollectionLoader collectionLoader;
|
||||
|
@ -267,10 +246,12 @@ public abstract class AbstractCollectionPersister
|
|||
Collection collectionBootDescriptor,
|
||||
CollectionDataAccess cacheAccessStrategy,
|
||||
RuntimeModelCreationContext creationContext) throws MappingException, CacheException {
|
||||
|
||||
final Value elementBootDescriptor = collectionBootDescriptor.getElement();
|
||||
|
||||
this.factory = creationContext.getSessionFactory();
|
||||
this.collectionSemantics = creationContext.getBootstrapContext()
|
||||
.getMetadataBuildingOptions()
|
||||
.getPersistentCollectionRepresentationResolver()
|
||||
.resolveRepresentation( collectionBootDescriptor );
|
||||
|
||||
this.cacheAccessStrategy = cacheAccessStrategy;
|
||||
if ( creationContext.getSessionFactoryOptions().isStructuredCacheEntriesEnabled() ) {
|
||||
cacheEntryStructure = collectionBootDescriptor.isMap()
|
||||
|
@ -285,19 +266,19 @@ public abstract class AbstractCollectionPersister
|
|||
sqlExceptionHelper = creationContext.getJdbcServices().getSqlExceptionHelper();
|
||||
collectionType = collectionBootDescriptor.getCollectionType();
|
||||
navigableRole = new NavigableRole( collectionBootDescriptor.getRole() );
|
||||
entityName = collectionBootDescriptor.getOwnerEntityName();
|
||||
ownerPersister = creationContext.getDomainModel().getEntityDescriptor( entityName );
|
||||
ownerPersister = creationContext.getDomainModel().getEntityDescriptor( collectionBootDescriptor.getOwnerEntityName() );
|
||||
queryLoaderName = collectionBootDescriptor.getLoaderName();
|
||||
isMutable = collectionBootDescriptor.isMutable();
|
||||
mappedByProperty = collectionBootDescriptor.getMappedByProperty();
|
||||
|
||||
Table table = collectionBootDescriptor.getCollectionTable();
|
||||
final Value elementBootDescriptor = collectionBootDescriptor.getElement();
|
||||
final Table table = collectionBootDescriptor.getCollectionTable();
|
||||
|
||||
fetchMode = elementBootDescriptor.getFetchMode();
|
||||
elementType = elementBootDescriptor.getType();
|
||||
// isSet = collectionBinding.isSet();
|
||||
// isSorted = collectionBinding.isSorted();
|
||||
isPrimitiveArray = collectionBootDescriptor.isPrimitiveArray();
|
||||
isArray = collectionBootDescriptor.isArray();
|
||||
subselectLoadable = collectionBootDescriptor.isSubselectLoadable();
|
||||
|
||||
qualifiedTableName = determineTableName( table );
|
||||
|
@ -420,7 +401,7 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
// INDEX AND ROW SELECT
|
||||
|
||||
hasIndex = collectionBootDescriptor.isIndexed();
|
||||
final boolean hasIndex = collectionBootDescriptor.isIndexed();
|
||||
if ( hasIndex ) {
|
||||
// NativeSQL: collect index column and auto-aliases
|
||||
IndexedCollection indexedCollection = (IndexedCollection) collectionBootDescriptor;
|
||||
|
@ -469,10 +450,6 @@ public abstract class AbstractCollectionPersister
|
|||
i++;
|
||||
}
|
||||
indexContainsFormula = hasFormula;
|
||||
//noinspection ConstantConditions
|
||||
baseIndex = indexedCollection.isList()
|
||||
? ( (List) indexedCollection ).getBaseIndex()
|
||||
: 0;
|
||||
}
|
||||
else {
|
||||
indexContainsFormula = false;
|
||||
|
@ -483,10 +460,9 @@ public abstract class AbstractCollectionPersister
|
|||
indexType = null;
|
||||
indexColumnNames = null;
|
||||
indexColumnAliases = null;
|
||||
baseIndex = 0;
|
||||
}
|
||||
|
||||
hasIdentifier = collectionBootDescriptor.isIdentified();
|
||||
final boolean hasIdentifier = collectionBootDescriptor.isIdentified();
|
||||
if ( hasIdentifier ) {
|
||||
if ( collectionBootDescriptor.isOneToMany() ) {
|
||||
throw new MappingException( "one-to-many collections with identifiers are not supported" );
|
||||
|
@ -588,11 +564,6 @@ public abstract class AbstractCollectionPersister
|
|||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// "mapping model"
|
||||
|
||||
this.collectionSemantics = creationContext.getBootstrapContext()
|
||||
.getMetadataBuildingOptions()
|
||||
.getPersistentCollectionRepresentationResolver()
|
||||
.resolveRepresentation( collectionBootDescriptor );
|
||||
|
||||
if ( queryLoaderName != null ) {
|
||||
final NamedQueryMemento namedQueryMemento = factory
|
||||
.getQueryEngine()
|
||||
|
@ -626,11 +597,6 @@ public abstract class AbstractCollectionPersister
|
|||
return navigableRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRole() {
|
||||
return navigableRole.getFullPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<?> getSortingComparator() {
|
||||
return comparator;
|
||||
|
@ -655,7 +621,6 @@ public abstract class AbstractCollectionPersister
|
|||
if ( attributeMapping.getIndexDescriptor() != null ) {
|
||||
collectionElementLoaderByIndex = new CollectionElementLoaderByIndex(
|
||||
attributeMapping,
|
||||
baseIndex,
|
||||
LoadQueryInfluencers.NONE,
|
||||
getFactory()
|
||||
);
|
||||
|
@ -793,11 +758,6 @@ public abstract class AbstractCollectionPersister
|
|||
return cacheAccessStrategy != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionType getCollectionType() {
|
||||
return collectionType;
|
||||
}
|
||||
|
||||
protected abstract RowMutationOperations getRowMutationOperations();
|
||||
protected abstract RemoveCoordinator getRemoveCoordinator();
|
||||
|
||||
|
@ -839,21 +799,6 @@ public abstract class AbstractCollectionPersister
|
|||
return hasWhere;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getIndexType() {
|
||||
return indexType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getElementType() {
|
||||
return elementType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the element class of an array, or null otherwise. needed by arrays
|
||||
*/
|
||||
|
@ -868,14 +813,16 @@ public abstract class AbstractCollectionPersister
|
|||
@Deprecated(forRemoval = true)
|
||||
@Remove
|
||||
protected Object decrementIndexByBase(Object index) {
|
||||
if ( baseIndex != 0 ) {
|
||||
final int baseIndex = attributeMapping.getIndexMetadata().getListIndexBase();
|
||||
if ( baseIndex > 0 ) {
|
||||
index = (Integer)index - baseIndex;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
protected Object incrementIndexByBase(Object index) {
|
||||
if ( baseIndex != 0 ) {
|
||||
final int baseIndex = attributeMapping.getIndexMetadata().getListIndexBase();
|
||||
if ( baseIndex > 0 ) {
|
||||
index = (Integer)index + baseIndex;
|
||||
}
|
||||
return index;
|
||||
|
@ -888,12 +835,12 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
@Override
|
||||
public boolean isArray() {
|
||||
return isArray;
|
||||
return collectionSemantics.getCollectionClassification() == CollectionClassification.ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifierColumnName() {
|
||||
if ( hasIdentifier ) {
|
||||
if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ID_BAG ) {
|
||||
return identifierColumnName;
|
||||
}
|
||||
else {
|
||||
|
@ -950,7 +897,7 @@ public abstract class AbstractCollectionPersister
|
|||
i++;
|
||||
}
|
||||
|
||||
if ( hasIndex ) {
|
||||
if ( hasIndex() ) {
|
||||
for ( String indexAlias : indexColumnAliases ) {
|
||||
sqlSelections.set(
|
||||
i,
|
||||
|
@ -963,7 +910,7 @@ public abstract class AbstractCollectionPersister
|
|||
i++;
|
||||
}
|
||||
}
|
||||
if ( hasIdentifier ) {
|
||||
if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ID_BAG ) {
|
||||
sqlSelections.set(
|
||||
i,
|
||||
new SqlSelectionImpl(
|
||||
|
@ -1088,7 +1035,7 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
@Override
|
||||
public boolean hasIndex() {
|
||||
return hasIndex;
|
||||
return collectionSemantics.getCollectionClassification().isIndexed();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1125,7 +1072,7 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
|
||||
public String getOwnerEntityName() {
|
||||
return entityName;
|
||||
return ownerPersister.getEntityName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1143,11 +1090,6 @@ public abstract class AbstractCollectionPersister
|
|||
return identifierGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getIdentifierType() {
|
||||
return identifierType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOrphanDelete() {
|
||||
return hasOrphanDelete;
|
||||
|
@ -1410,10 +1352,10 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
initCollectionPropertyMap( "key", keyType, keyColumnAliases );
|
||||
initCollectionPropertyMap( "element", elementType, elementColumnAliases );
|
||||
if ( hasIndex ) {
|
||||
if ( hasIndex() ) {
|
||||
initCollectionPropertyMap( "index", indexType, indexColumnAliases );
|
||||
}
|
||||
if ( hasIdentifier ) {
|
||||
if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ID_BAG ) {
|
||||
initCollectionPropertyMap( "id", identifierType, new String[] { identifierColumnAlias } );
|
||||
}
|
||||
}
|
||||
|
@ -1445,6 +1387,7 @@ public abstract class AbstractCollectionPersister
|
|||
getKeyType().nullSafeSet( st, key, 1, session );
|
||||
ResultSet rs = jdbcCoordinator.getResultSetReturn().extract( st );
|
||||
try {
|
||||
final int baseIndex = Math.max( attributeMapping.getIndexMetadata().getListIndexBase(), 0 );
|
||||
return rs.next() ? rs.getInt( 1 ) - baseIndex : 0;
|
||||
}
|
||||
finally {
|
||||
|
@ -1617,7 +1560,7 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
@Override
|
||||
public boolean hasPhysicalIndexColumn() {
|
||||
return hasIndex && !indexContainsFormula;
|
||||
return hasIndex() && !indexContainsFormula;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1791,6 +1734,56 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Types (the methods are already deprecated on CollectionPersister)
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Deprecated private final CollectionType collectionType;
|
||||
@Deprecated private final Type keyType;
|
||||
@Deprecated private final Type identifierType;
|
||||
@Deprecated private final Type indexType;
|
||||
@Deprecated protected final Type elementType;
|
||||
|
||||
public CollectionType getCollectionType() {
|
||||
return collectionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getIdentifierType() {
|
||||
return identifierType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getIndexType() {
|
||||
return indexType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getElementType() {
|
||||
return elementType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// State related to this we handle differently in 6+. In other words, state
|
||||
// that is no longer needed
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Deprecated protected final String[] keyColumnAliases;
|
||||
@Deprecated private final String identifierColumnAlias;
|
||||
@Deprecated protected final String[] indexColumnAliases;
|
||||
@Deprecated protected final String[] elementColumnAliases;
|
||||
@Deprecated private final Map<String,String[]> collectionPropertyColumnAliases = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public String[] getKeyColumnAliases(String suffix) {
|
||||
|
@ -1804,7 +1797,7 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
@Override
|
||||
public String[] getIndexColumnAliases(String suffix) {
|
||||
if ( hasIndex ) {
|
||||
if ( hasIndex() ) {
|
||||
return new Alias( suffix ).toAliasStrings( indexColumnAliases );
|
||||
}
|
||||
else {
|
||||
|
@ -1814,7 +1807,7 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
@Override
|
||||
public String getIdentifierColumnAlias(String suffix) {
|
||||
if ( hasIdentifier ) {
|
||||
if ( collectionSemantics.getCollectionClassification() == CollectionClassification.ID_BAG ) {
|
||||
return new Alias( suffix ).toAliasString( identifierColumnAlias );
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -640,7 +640,7 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
|
|||
else {
|
||||
deleteBuilder.addKeyRestrictionsLeniently( pluralAttribute.getKeyDescriptor().getKeyPart() );
|
||||
|
||||
if ( hasIndex && !indexContainsFormula ) {
|
||||
if ( hasIndex() && !indexContainsFormula ) {
|
||||
assert pluralAttribute.getIndexDescriptor() != null;
|
||||
deleteBuilder.addKeyRestrictionsLeniently( pluralAttribute.getIndexDescriptor() );
|
||||
}
|
||||
|
|
|
@ -80,15 +80,24 @@ import org.hibernate.type.Type;
|
|||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* @see QueryableCollection
|
||||
* @see PersistentCollection
|
||||
* @see PluralAttributeMapping
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public interface CollectionPersister extends Restrictable {
|
||||
/**
|
||||
* The NavigableRole for this collection.
|
||||
*/
|
||||
NavigableRole getNavigableRole();
|
||||
|
||||
String getRole();
|
||||
default String getRole() {
|
||||
return getNavigableRole().getFullPath();
|
||||
}
|
||||
|
||||
default PluralAttributeMapping getAttributeMapping() {
|
||||
throw new UnsupportedOperationException( "CollectionPersister used for [" + getRole() + "] does not support SQL AST" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the persister of the entity that "owns" this collection
|
||||
|
@ -123,22 +132,6 @@ public interface CollectionPersister extends Restrictable {
|
|||
*/
|
||||
CacheEntryStructure getCacheEntryStructure();
|
||||
|
||||
/**
|
||||
* Get the associated {@code Type}
|
||||
*/
|
||||
CollectionType getCollectionType();
|
||||
/**
|
||||
* Get the "key" type (the type of the foreign key)
|
||||
*/
|
||||
Type getKeyType();
|
||||
/**
|
||||
* Get the "index" type for a list or map (optional operation)
|
||||
*/
|
||||
Type getIndexType();
|
||||
/**
|
||||
* Get the "element" type
|
||||
*/
|
||||
Type getElementType();
|
||||
/**
|
||||
* Return the element class of an array, or null otherwise
|
||||
*/
|
||||
|
@ -245,11 +238,6 @@ public interface CollectionPersister extends Restrictable {
|
|||
return getIdentifierGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the surrogate key
|
||||
*/
|
||||
Type getIdentifierType();
|
||||
|
||||
/**
|
||||
* Does this collection implement "orphan delete"?
|
||||
*/
|
||||
|
@ -302,10 +290,6 @@ public interface CollectionPersister extends Restrictable {
|
|||
|
||||
boolean isAffectedByEnabledFilters(SharedSessionContractImplementor session);
|
||||
|
||||
default PluralAttributeMapping getAttributeMapping() {
|
||||
throw new UnsupportedOperationException( "CollectionPersister used for [" + getRole() + "] does not support SQL AST" );
|
||||
}
|
||||
|
||||
default boolean isAffectedByEnabledFilters(LoadQueryInfluencers influencers) {
|
||||
throw new UnsupportedOperationException( "CollectionPersister used for [" + getRole() + "] does not support SQL AST" );
|
||||
}
|
||||
|
@ -408,4 +392,54 @@ public interface CollectionPersister extends Restrictable {
|
|||
*/
|
||||
@Deprecated( since = "6", forRemoval = true )
|
||||
String getIdentifierColumnAlias(String suffix);
|
||||
|
||||
/**
|
||||
* Get the associated {@code Type}
|
||||
*
|
||||
* @deprecated Hibernate is moving away from {@link Type}. Corresponding
|
||||
* {@linkplain org.hibernate.metamodel.mapping mapping metamodel} calls should
|
||||
* be used instead - here (generally), {@link PluralAttributeMapping}
|
||||
*/
|
||||
@Deprecated( forRemoval = true )
|
||||
CollectionType getCollectionType();
|
||||
|
||||
/**
|
||||
* Get the "key" type (the type of the foreign key)
|
||||
*
|
||||
* @deprecated Hibernate is moving away from {@link Type}. Corresponding
|
||||
* {@linkplain org.hibernate.metamodel.mapping mapping metamodel} calls should
|
||||
* be used instead - here, {@link PluralAttributeMapping#getKeyDescriptor()}
|
||||
*/
|
||||
@Deprecated( forRemoval = true )
|
||||
Type getKeyType();
|
||||
|
||||
/**
|
||||
* Get the "index" type for a list or map (optional operation)
|
||||
*
|
||||
* @deprecated Hibernate is moving away from {@link Type}. Corresponding
|
||||
* {@linkplain org.hibernate.metamodel.mapping mapping metamodel} calls should
|
||||
* be used instead - here, {@link PluralAttributeMapping#getIndexDescriptor()}
|
||||
*/
|
||||
@Deprecated( forRemoval = true )
|
||||
Type getIndexType();
|
||||
|
||||
/**
|
||||
* Get the "element" type
|
||||
*
|
||||
* @deprecated Hibernate is moving away from {@link Type}. Corresponding
|
||||
* {@linkplain org.hibernate.metamodel.mapping mapping metamodel} calls should
|
||||
* be used instead - here, {@link PluralAttributeMapping#getElementDescriptor()}
|
||||
*/
|
||||
@Deprecated( forRemoval = true )
|
||||
Type getElementType();
|
||||
|
||||
/**
|
||||
* Get the type of the surrogate key
|
||||
*
|
||||
* @deprecated Hibernate is moving away from {@link Type}. Corresponding
|
||||
* {@linkplain org.hibernate.metamodel.mapping mapping metamodel} calls should
|
||||
* be used instead - here, {@link PluralAttributeMapping#getIdentifierDescriptor()}
|
||||
*/
|
||||
@Deprecated( forRemoval = true )
|
||||
Type getIdentifierType();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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.collection;
|
||||
|
||||
import org.hibernate.metadata.CollectionMetadata;
|
||||
|
||||
/**
|
||||
* @deprecated Just used to singly extend all the deprecated collection persister roles
|
||||
*/
|
||||
@Deprecated
|
||||
public interface DeprecatedCollectionStuff extends SQLLoadableCollection, CollectionMetadata {
|
||||
@Override
|
||||
default String getRole() {
|
||||
return SQLLoadableCollection.super.getRole();
|
||||
}
|
||||
}
|
|
@ -213,7 +213,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
|
||||
// If one-to-many and inverse, still need to create the index. See HHH-5732.
|
||||
final boolean doWrite = isInverse
|
||||
&& hasIndex
|
||||
&& hasIndex()
|
||||
&& !indexContainsFormula
|
||||
&& ArrayHelper.countTrue( indexColumnIsSettable ) > 0;
|
||||
if ( !doWrite ) {
|
||||
|
@ -328,7 +328,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
assert fkDescriptor != null;
|
||||
|
||||
final int keyColumnCount = fkDescriptor.getJdbcTypeCount();
|
||||
final int valuesCount = hasIndex
|
||||
final int valuesCount = hasIndex()
|
||||
? keyColumnCount + indexColumnNames.length
|
||||
: keyColumnCount;
|
||||
|
||||
|
@ -360,7 +360,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
);
|
||||
}
|
||||
|
||||
if ( hasIndex && !indexContainsFormula ) {
|
||||
if ( hasIndex() && !indexContainsFormula ) {
|
||||
getAttributeMapping().getIndexDescriptor().forEachSelectable( (selectionIndex, selectableMapping) -> {
|
||||
if ( ! selectableMapping.isUpdateable() ) {
|
||||
return;
|
||||
|
@ -402,7 +402,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
final RowMutationOperations.Values writeIndexValues;
|
||||
final RowMutationOperations.Restrictions writeIndexRestrictions;
|
||||
final boolean needsWriteIndex = isInverse
|
||||
&& hasIndex
|
||||
&& hasIndex()
|
||||
&& !indexContainsFormula
|
||||
&& !ArrayHelper.isAllFalse( indexColumnIsSettable );
|
||||
if ( needsWriteIndex ) {
|
||||
|
@ -592,7 +592,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
}
|
||||
|
||||
// set the value for each index column to null
|
||||
if ( hasIndex && !indexContainsFormula ) {
|
||||
if ( hasIndex() && !indexContainsFormula ) {
|
||||
final CollectionPart indexDescriptor = getAttributeMapping().getIndexDescriptor();
|
||||
assert indexDescriptor != null;
|
||||
|
||||
|
|
|
@ -309,20 +309,15 @@ import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnRefere
|
|||
*/
|
||||
@Internal
|
||||
public abstract class AbstractEntityPersister
|
||||
implements OuterJoinLoadable, ClassMetadata, UniqueKeyLoadable,
|
||||
SQLLoadable, LazyPropertyInitializer, PostInsertIdentityPersister, Lockable,
|
||||
org.hibernate.persister.entity.Queryable, InFlightEntityMappingType, EntityMutationTarget {
|
||||
implements InFlightEntityMappingType, EntityMutationTarget, LazyPropertyInitializer, PostInsertIdentityPersister, DeprecatedEntityStuff {
|
||||
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractEntityPersister.class );
|
||||
|
||||
public static final String ENTITY_CLASS = "class";
|
||||
public static final String VERSION_COLUMN_ALIAS = "version_";
|
||||
|
||||
private final SessionFactoryImplementor factory;
|
||||
|
||||
private final NavigableRole navigableRole;
|
||||
|
||||
private final EntityMetamodel entityMetamodel;
|
||||
private final SessionFactoryImplementor factory;
|
||||
private final EntityEntryFactory entityEntryFactory;
|
||||
|
||||
private final String sqlAliasStem;
|
||||
|
@ -332,18 +327,6 @@ public abstract class AbstractEntityPersister
|
|||
private NaturalIdLoader<?> naturalIdLoader;
|
||||
private MultiNaturalIdLoader<?> multiNaturalIdLoader;
|
||||
|
||||
private SqmMultiTableMutationStrategy sqmMultiTableMutationStrategy;
|
||||
private SqmMultiTableInsertStrategy sqmMultiTableInsertStrategy;
|
||||
|
||||
private final EntityDataAccess cacheAccessStrategy;
|
||||
private final NaturalIdDataAccess naturalIdRegionAccessStrategy;
|
||||
private final CacheEntryHelper cacheEntryHelper;
|
||||
private final boolean canReadFromCache;
|
||||
private final boolean canWriteToCache;
|
||||
private final boolean invalidateCache;
|
||||
private final boolean isLazyPropertiesCacheable;
|
||||
private final boolean useReferenceCacheEntries;
|
||||
|
||||
private final String[] rootTableKeyColumnNames;
|
||||
private final String[] rootTableKeyColumnReaders;
|
||||
private final String[] rootTableKeyColumnReaderTemplates;
|
||||
|
@ -392,47 +375,39 @@ public abstract class AbstractEntityPersister
|
|||
private final boolean[] propertyDefinedOnSubclass;
|
||||
private final CascadeStyle[] subclassPropertyCascadeStyleClosure;
|
||||
|
||||
//information about all columns/formulas in class hierarchy
|
||||
private final String[] subclassColumnAliasClosure;
|
||||
private final String[] subclassFormulaAliasClosure;
|
||||
|
||||
// dynamic filters attached to the class-level
|
||||
private final FilterHelper filterHelper;
|
||||
private volatile Set<String> affectingFetchProfileNames;
|
||||
|
||||
private Map<String, SingleIdArrayLoadPlan> lazyLoadPlanByFetchGroup;
|
||||
private final LockModeEnumMap<LockingStrategy> lockers = new LockModeEnumMap<>();
|
||||
private String sqlVersionSelectString;
|
||||
|
||||
private EntityTableMapping[] tableMappings;
|
||||
private InsertCoordinator insertCoordinator;
|
||||
private UpdateCoordinator updateCoordinator;
|
||||
private DeleteCoordinator deleteCoordinator;
|
||||
|
||||
protected Expectation[] insertExpectations;
|
||||
protected Expectation[] updateExpectations;
|
||||
protected Expectation[] deleteExpectations;
|
||||
private SqmMultiTableMutationStrategy sqmMultiTableMutationStrategy;
|
||||
private SqmMultiTableInsertStrategy sqmMultiTableInsertStrategy;
|
||||
|
||||
// SQL strings
|
||||
private String sqlVersionSelectString;
|
||||
private Map<String, SingleIdArrayLoadPlan> lazyLoadPlanByFetchGroup;
|
||||
private final EntityDataAccess cacheAccessStrategy;
|
||||
private final NaturalIdDataAccess naturalIdRegionAccessStrategy;
|
||||
private final CacheEntryHelper cacheEntryHelper;
|
||||
private final boolean canReadFromCache;
|
||||
private final boolean canWriteToCache;
|
||||
private final boolean invalidateCache;
|
||||
private final boolean isLazyPropertiesCacheable;
|
||||
private final boolean useReferenceCacheEntries;
|
||||
|
||||
// dynamic filters attached to the class-level
|
||||
private final FilterHelper filterHelper;
|
||||
private volatile Set<String> affectingFetchProfileNames;
|
||||
|
||||
private GeneratedValuesProcessor insertGeneratedValuesProcessor;
|
||||
private GeneratedValuesProcessor updateGeneratedValuesProcessor;
|
||||
|
||||
//Custom SQL (would be better if these were private)
|
||||
protected boolean[] insertCallable;
|
||||
protected boolean[] updateCallable;
|
||||
protected boolean[] deleteCallable;
|
||||
protected String[] customSQLInsert;
|
||||
protected String[] customSQLUpdate;
|
||||
protected String[] customSQLDelete;
|
||||
|
||||
private InsertGeneratedIdentifierDelegate identityDelegate;
|
||||
private String identitySelectString;
|
||||
|
||||
private boolean[] tableHasColumns;
|
||||
|
||||
private final Map<String,String[]> subclassPropertyAliases = new HashMap<>();
|
||||
private final Map<String,String[]> subclassPropertyColumnNames = new HashMap<>();
|
||||
|
||||
private final JavaType<?> javaType;
|
||||
|
@ -455,7 +430,6 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
protected ReflectionOptimizer.AccessOptimizer accessOptimizer;
|
||||
|
||||
// private final String[] fullDiscriminatorSQLValues;
|
||||
private final Object[] fullDiscriminatorValues;
|
||||
|
||||
/**
|
||||
|
@ -938,10 +912,6 @@ public abstract class AbstractEntityPersister
|
|||
: Template.TEMPLATE + "." + DISCRIMINATOR_ALIAS;
|
||||
}
|
||||
|
||||
public String getDiscriminatorAlias() {
|
||||
return DISCRIMINATOR_ALIAS;
|
||||
}
|
||||
|
||||
public String getDiscriminatorFormulaTemplate() {
|
||||
return null;
|
||||
}
|
||||
|
@ -2468,136 +2438,12 @@ public abstract class AbstractEntityPersister
|
|||
);
|
||||
}
|
||||
|
||||
// returns the aliases of the selectable columns
|
||||
protected String[] getSubclassColumnAliasClosure() {
|
||||
return subclassColumnAliasClosure;
|
||||
}
|
||||
|
||||
protected String[] getSubclassFormulaAliasClosure() {
|
||||
return subclassFormulaAliasClosure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSubclassPropertyColumnAliases(String propertyName, String suffix) {
|
||||
final String[] rawAliases = subclassPropertyAliases.get( propertyName );
|
||||
if ( rawAliases == null ) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
final String[] result = new String[rawAliases.length];
|
||||
for ( int i = 0; i < rawAliases.length; i++ ) {
|
||||
result[i] = new Alias( suffix ).toUnquotedAliasString( rawAliases[i] );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSubclassPropertyColumnNames(String propertyName) {
|
||||
//TODO: should we allow suffixes on these ?
|
||||
return subclassPropertyColumnNames.get( propertyName );
|
||||
}
|
||||
|
||||
|
||||
//This is really ugly, but necessary:
|
||||
|
||||
/**
|
||||
* Must be called by subclasses, at the end of their constructors
|
||||
*/
|
||||
protected void initSubclassPropertyAliasesMap(PersistentClass model) throws MappingException {
|
||||
|
||||
// ALIASES
|
||||
internalInitSubclassPropertyAliasesMap( null, model.getSubclassPropertyClosure() );
|
||||
|
||||
// aliases for identifier ( alias.id ); skip if the entity defines a non-id property named 'id'
|
||||
if ( !entityMetamodel.hasNonIdentifierPropertyNamedId() ) {
|
||||
subclassPropertyAliases.put( ENTITY_ID, getIdentifierAliases() );
|
||||
subclassPropertyColumnNames.put( ENTITY_ID, getIdentifierColumnNames() );
|
||||
}
|
||||
|
||||
// aliases named identifier ( alias.idname )
|
||||
if ( hasIdentifierProperty() ) {
|
||||
subclassPropertyAliases.put( getIdentifierPropertyName(), getIdentifierAliases() );
|
||||
subclassPropertyColumnNames.put( getIdentifierPropertyName(), getIdentifierColumnNames() );
|
||||
}
|
||||
|
||||
// aliases for composite-id's
|
||||
if ( getIdentifierType().isComponentType() ) {
|
||||
// Fetch embedded identifiers property names from the "virtual" identifier component
|
||||
final CompositeType componentId = (CompositeType) getIdentifierType();
|
||||
final String[] idPropertyNames = componentId.getPropertyNames();
|
||||
final String[] idAliases = getIdentifierAliases();
|
||||
final String[] idColumnNames = getIdentifierColumnNames();
|
||||
|
||||
for ( int i = 0; i < idPropertyNames.length; i++ ) {
|
||||
if ( entityMetamodel.hasNonIdentifierPropertyNamedId() ) {
|
||||
subclassPropertyAliases.put(
|
||||
ENTITY_ID + "." + idPropertyNames[i],
|
||||
new String[] {idAliases[i]}
|
||||
);
|
||||
subclassPropertyColumnNames.put(
|
||||
ENTITY_ID + "." + getIdentifierPropertyName() + "." + idPropertyNames[i],
|
||||
new String[] {idColumnNames[i]}
|
||||
);
|
||||
}
|
||||
// if (hasIdentifierProperty() && !ENTITY_ID.equals( getIdentifierPropertyNames() ) ) {
|
||||
if ( hasIdentifierProperty() ) {
|
||||
subclassPropertyAliases.put(
|
||||
getIdentifierPropertyName() + "." + idPropertyNames[i],
|
||||
new String[] {idAliases[i]}
|
||||
);
|
||||
subclassPropertyColumnNames.put(
|
||||
getIdentifierPropertyName() + "." + idPropertyNames[i],
|
||||
new String[] {idColumnNames[i]}
|
||||
);
|
||||
}
|
||||
else {
|
||||
// embedded composite ids ( alias.idName1, alias.idName2 )
|
||||
subclassPropertyAliases.put( idPropertyNames[i], new String[] {idAliases[i]} );
|
||||
subclassPropertyColumnNames.put( idPropertyNames[i], new String[] {idColumnNames[i]} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( entityMetamodel.isPolymorphic() ) {
|
||||
subclassPropertyAliases.put( ENTITY_CLASS, new String[] {getDiscriminatorAlias()} );
|
||||
subclassPropertyColumnNames.put( ENTITY_CLASS, new String[] {getDiscriminatorColumnName()} );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void internalInitSubclassPropertyAliasesMap(String path, List<Property> properties) {
|
||||
for (Property property : properties) {
|
||||
final String name = path == null ? property.getName() : path + "." + property.getName();
|
||||
if ( property.isComposite() ) {
|
||||
Component component = (Component) property.getValue();
|
||||
internalInitSubclassPropertyAliasesMap( name, component.getProperties() );
|
||||
}
|
||||
|
||||
String[] aliases = new String[property.getColumnSpan()];
|
||||
String[] cols = new String[property.getColumnSpan()];
|
||||
int l = 0;
|
||||
for ( Selectable selectable: property.getSelectables() ) {
|
||||
Dialect dialect = getFactory().getJdbcServices().getDialect();
|
||||
aliases[l] = selectable.getAlias( dialect, property.getValue().getTable() );
|
||||
cols[l] = selectable.getText(dialect); // TODO: skip formulas?
|
||||
l++;
|
||||
}
|
||||
|
||||
subclassPropertyAliases.put( name, aliases );
|
||||
subclassPropertyColumnNames.put( name, cols );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Hibernate Reactive
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
protected String[][] getLazyPropertyColumnAliases() {
|
||||
return lazyPropertyColumnAliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object loadByUniqueKey(
|
||||
String propertyName,
|
||||
|
@ -5954,8 +5800,13 @@ public abstract class AbstractEntityPersister
|
|||
return hasPartitionedSelectionMapping;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Deprecations
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* @deprecated With no replacement
|
||||
|
@ -6252,4 +6103,193 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// State built and stored here during instantiation, and only used in other
|
||||
// phases of initialization
|
||||
// - postConstruct
|
||||
// - postInstantiate
|
||||
// - prepareMappingModel
|
||||
// - ...
|
||||
//
|
||||
// This is effectively bootstrap state that is kept around during runtime.
|
||||
//
|
||||
// Would be better to encapsulate and store this state relative to the
|
||||
// `PersisterCreationContext` so it can get released after bootstrap
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Deprecated protected Expectation[] insertExpectations;
|
||||
@Deprecated protected Expectation[] updateExpectations;
|
||||
@Deprecated protected Expectation[] deleteExpectations;
|
||||
|
||||
@Deprecated protected boolean[] insertCallable;
|
||||
@Deprecated protected boolean[] updateCallable;
|
||||
@Deprecated protected boolean[] deleteCallable;
|
||||
|
||||
@Deprecated protected String[] customSQLInsert;
|
||||
@Deprecated protected String[] customSQLUpdate;
|
||||
@Deprecated protected String[] customSQLDelete;
|
||||
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// State related to this we handle differently in 6+. In other words, state
|
||||
// that is no longer needed
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Deprecated private final EntityMetamodel entityMetamodel;
|
||||
|
||||
@Deprecated private final String[] subclassColumnAliasClosure;
|
||||
@Deprecated private final String[] subclassFormulaAliasClosure;
|
||||
@Deprecated private final Map<String,String[]> subclassPropertyAliases = new HashMap<>();
|
||||
|
||||
/**
|
||||
* @deprecated Hibernate no longer uses aliases to read from result sets
|
||||
*/
|
||||
@Deprecated protected String[] getSubclassColumnAliasClosure() {
|
||||
return subclassColumnAliasClosure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Hibernate no longer uses aliases to read from result sets
|
||||
*/
|
||||
@Deprecated protected String[] getSubclassFormulaAliasClosure() {
|
||||
return subclassFormulaAliasClosure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Hibernate no longer uses aliases to read from result sets
|
||||
*/
|
||||
@Deprecated @Override
|
||||
public String[] getSubclassPropertyColumnAliases(String propertyName, String suffix) {
|
||||
final String[] rawAliases = subclassPropertyAliases.get( propertyName );
|
||||
if ( rawAliases == null ) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
final String[] result = new String[rawAliases.length];
|
||||
for ( int i = 0; i < rawAliases.length; i++ ) {
|
||||
result[i] = new Alias( suffix ).toUnquotedAliasString( rawAliases[i] );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called by subclasses, at the end of their constructors
|
||||
*
|
||||
* @deprecated Hibernate no longer uses aliases to read from result sets
|
||||
*/
|
||||
@Deprecated protected void initSubclassPropertyAliasesMap(PersistentClass model) throws MappingException {
|
||||
|
||||
// ALIASES
|
||||
internalInitSubclassPropertyAliasesMap( null, model.getSubclassPropertyClosure() );
|
||||
|
||||
// aliases for identifier ( alias.id ); skip if the entity defines a non-id property named 'id'
|
||||
if ( !entityMetamodel.hasNonIdentifierPropertyNamedId() ) {
|
||||
subclassPropertyAliases.put( ENTITY_ID, getIdentifierAliases() );
|
||||
subclassPropertyColumnNames.put( ENTITY_ID, getIdentifierColumnNames() );
|
||||
}
|
||||
|
||||
// aliases named identifier ( alias.idname )
|
||||
if ( hasIdentifierProperty() ) {
|
||||
subclassPropertyAliases.put( getIdentifierPropertyName(), getIdentifierAliases() );
|
||||
subclassPropertyColumnNames.put( getIdentifierPropertyName(), getIdentifierColumnNames() );
|
||||
}
|
||||
|
||||
// aliases for composite-id's
|
||||
if ( getIdentifierType().isComponentType() ) {
|
||||
// Fetch embedded identifiers property names from the "virtual" identifier component
|
||||
final CompositeType componentId = (CompositeType) getIdentifierType();
|
||||
final String[] idPropertyNames = componentId.getPropertyNames();
|
||||
final String[] idAliases = getIdentifierAliases();
|
||||
final String[] idColumnNames = getIdentifierColumnNames();
|
||||
|
||||
for ( int i = 0; i < idPropertyNames.length; i++ ) {
|
||||
if ( entityMetamodel.hasNonIdentifierPropertyNamedId() ) {
|
||||
subclassPropertyAliases.put(
|
||||
ENTITY_ID + "." + idPropertyNames[i],
|
||||
new String[] {idAliases[i]}
|
||||
);
|
||||
subclassPropertyColumnNames.put(
|
||||
ENTITY_ID + "." + getIdentifierPropertyName() + "." + idPropertyNames[i],
|
||||
new String[] {idColumnNames[i]}
|
||||
);
|
||||
}
|
||||
// if (hasIdentifierProperty() && !ENTITY_ID.equals( getIdentifierPropertyNames() ) ) {
|
||||
if ( hasIdentifierProperty() ) {
|
||||
subclassPropertyAliases.put(
|
||||
getIdentifierPropertyName() + "." + idPropertyNames[i],
|
||||
new String[] {idAliases[i]}
|
||||
);
|
||||
subclassPropertyColumnNames.put(
|
||||
getIdentifierPropertyName() + "." + idPropertyNames[i],
|
||||
new String[] {idColumnNames[i]}
|
||||
);
|
||||
}
|
||||
else {
|
||||
// embedded composite ids ( alias.idName1, alias.idName2 )
|
||||
subclassPropertyAliases.put( idPropertyNames[i], new String[] {idAliases[i]} );
|
||||
subclassPropertyColumnNames.put( idPropertyNames[i], new String[] {idColumnNames[i]} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( entityMetamodel.isPolymorphic() ) {
|
||||
subclassPropertyAliases.put( ENTITY_CLASS, new String[] {getDiscriminatorAlias()} );
|
||||
subclassPropertyColumnNames.put( ENTITY_CLASS, new String[] {getDiscriminatorColumnName()} );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void internalInitSubclassPropertyAliasesMap(String path, List<Property> properties) {
|
||||
for (Property property : properties) {
|
||||
final String name = path == null ? property.getName() : path + "." + property.getName();
|
||||
if ( property.isComposite() ) {
|
||||
Component component = (Component) property.getValue();
|
||||
internalInitSubclassPropertyAliasesMap( name, component.getProperties() );
|
||||
}
|
||||
|
||||
String[] aliases = new String[property.getColumnSpan()];
|
||||
String[] cols = new String[property.getColumnSpan()];
|
||||
int l = 0;
|
||||
for ( Selectable selectable: property.getSelectables() ) {
|
||||
Dialect dialect = getFactory().getJdbcServices().getDialect();
|
||||
aliases[l] = selectable.getAlias( dialect, property.getValue().getTable() );
|
||||
cols[l] = selectable.getText(dialect); // TODO: skip formulas?
|
||||
l++;
|
||||
}
|
||||
|
||||
subclassPropertyAliases.put( name, aliases );
|
||||
subclassPropertyColumnNames.put( name, cols );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Hibernate Reactive
|
||||
*
|
||||
* @deprecated Hibernate no longer uses aliases to read from result sets
|
||||
*/
|
||||
@Deprecated @SuppressWarnings("unused")
|
||||
protected String[][] getLazyPropertyColumnAliases() {
|
||||
return lazyPropertyColumnAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Hibernate no longer uses aliases to read from result sets
|
||||
*/
|
||||
@Deprecated
|
||||
public String getDiscriminatorAlias() {
|
||||
return DISCRIMINATOR_ALIAS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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 org.hibernate.metadata.ClassMetadata;
|
||||
|
||||
/**
|
||||
* @deprecated Just used to singly extend all the deprecated entity persister roles
|
||||
*/
|
||||
@Deprecated
|
||||
public interface DeprecatedEntityStuff
|
||||
extends OuterJoinLoadable, ClassMetadata, UniqueKeyLoadable, SQLLoadable, Lockable, org.hibernate.persister.entity.Queryable {
|
||||
}
|
|
@ -590,6 +590,14 @@ public interface EntityPersister extends EntityMappingType, RootTableGroupProduc
|
|||
*/
|
||||
List<?> multiLoad(Object[] ids, EventSource session, MultiIdLoadOptions loadOptions);
|
||||
|
||||
@Override
|
||||
default Object loadByUniqueKey(String propertyName, Object uniqueKey, SharedSessionContractImplementor session) {
|
||||
throw new UnsupportedOperationException(
|
||||
"EntityPersister implementation '" + getClass().getName()
|
||||
+ "' does not support 'UniqueKeyLoadable'"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do a version check (optional operation)
|
||||
*/
|
||||
|
|
|
@ -113,7 +113,6 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
|||
private final String discriminatorColumnReaders;
|
||||
private final String discriminatorColumnReaderTemplate;
|
||||
private final String discriminatorFormulaTemplate;
|
||||
private final String discriminatorAlias;
|
||||
private final BasicType<?> discriminatorType;
|
||||
private final Object discriminatorValue;
|
||||
private final String discriminatorSQLValue;
|
||||
|
@ -122,11 +121,6 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
|||
private final String[] constraintOrderedTableNames;
|
||||
private final String[][] constraintOrderedKeyColumnNames;
|
||||
|
||||
//private final Map propertyTableNumbersByName = new HashMap();
|
||||
// private final Map<String, Integer> propertyTableNumbersByNameAndSubclass;
|
||||
|
||||
//INITIALIZATION:
|
||||
|
||||
@Deprecated(since = "6.0")
|
||||
public SingleTableEntityPersister(
|
||||
final PersistentClass persistentClass,
|
||||
|
@ -321,7 +315,6 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
|||
discriminatorInsertable = isDiscriminatorInsertable( persistentClass );
|
||||
if ( discriminator.hasFormula() ) {
|
||||
final Formula formula = (Formula) selectable;
|
||||
// discriminatorFormula = formula.getFormula();
|
||||
discriminatorFormulaTemplate = formula.getTemplate( dialect, typeConfiguration, functionRegistry );
|
||||
discriminatorColumnName = null;
|
||||
discriminatorColumnReaders = null;
|
||||
|
@ -334,7 +327,6 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
|||
discriminatorColumnReaders = column.getReadExpr( dialect );
|
||||
discriminatorColumnReaderTemplate = column.getTemplate( dialect, typeConfiguration, functionRegistry );
|
||||
discriminatorAlias = column.getAlias( dialect, persistentClass.getRootTable() );
|
||||
// discriminatorFormula = null;
|
||||
discriminatorFormulaTemplate = null;
|
||||
}
|
||||
}
|
||||
|
@ -452,11 +444,6 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
|||
return discriminatorColumnReaderTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDiscriminatorAlias() {
|
||||
return discriminatorAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDiscriminatorFormulaTemplate() {
|
||||
return discriminatorFormulaTemplate;
|
||||
|
@ -748,4 +735,17 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Deprecations
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Deprecated private final String discriminatorAlias;
|
||||
|
||||
@Override
|
||||
public String getDiscriminatorAlias() {
|
||||
return discriminatorAlias;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,10 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|||
* An {@link EntityPersister} that can be loaded by a non-primary unique key.
|
||||
*
|
||||
* @author Gavin King
|
||||
*
|
||||
* @deprecated Use {@link org.hibernate.metamodel.mapping.EntityMappingType#loadByUniqueKey} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public interface UniqueKeyLoadable extends Loadable {
|
||||
/**
|
||||
* Load an instance of the persistent class, by a unique key other
|
||||
|
|
|
@ -16,5 +16,12 @@
|
|||
* defines a mechanism for persisting instances of a given
|
||||
* collection role.
|
||||
* </ul>
|
||||
*
|
||||
* @apiNote This package is considered an SPI, meaning it is intended for use
|
||||
* by internal code and by integrations. It is not supported for application use.
|
||||
* Be aware that its backwards compatibility guarantee is tied defined by SPI which
|
||||
* is less strict than API, which <b>is</b> intended for application use (things
|
||||
* like {@link org.hibernate.SessionFactory}, {@link org.hibernate.Session},
|
||||
* {@link org.hibernate.Transaction}, etc.).
|
||||
*/
|
||||
package org.hibernate.persister;
|
||||
|
|
|
@ -674,6 +674,11 @@ public class AnonymousTupleEntityValuedModelPart
|
|||
delegate.getEntityMappingType().visitConstraintOrderedTables( consumer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object loadByUniqueKey(String propertyName, Object uniqueKey, SharedSessionContractImplementor session) {
|
||||
return delegate.getEntityMappingType().loadByUniqueKey( propertyName, uniqueKey, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NaturalIdLoader<?> getNaturalIdLoader() {
|
||||
return delegate.getEntityMappingType().getNaturalIdLoader();
|
||||
|
|
|
@ -17,7 +17,6 @@ import org.hibernate.internal.log.LoggingHelper;
|
|||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.UniqueKeyLoadable;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
|
@ -147,7 +146,7 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
|||
&& isEnhancedForLazyLoading( parentEntityInitializer ) ) {
|
||||
return;
|
||||
}
|
||||
entityInstance = ( (UniqueKeyLoadable) concreteDescriptor ).loadByUniqueKey(
|
||||
entityInstance = concreteDescriptor.loadByUniqueKey(
|
||||
uniqueKeyPropertyName,
|
||||
identifier,
|
||||
session
|
||||
|
|
|
@ -11,7 +11,6 @@ import org.hibernate.engine.spi.PersistenceContext;
|
|||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.UniqueKeyLoadable;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||
|
@ -83,7 +82,7 @@ public class EntitySelectFetchByUniqueKeyInitializer extends EntitySelectFetchIn
|
|||
final JdbcValuesSourceProcessingState jdbcValuesSourceProcessingState = rowProcessingState.getJdbcValuesSourceProcessingState();
|
||||
jdbcValuesSourceProcessingState.registerInitializer( euk, this );
|
||||
|
||||
entityInstance = ( (UniqueKeyLoadable) concreteDescriptor ).loadByUniqueKey(
|
||||
entityInstance = concreteDescriptor.loadByUniqueKey(
|
||||
uniqueKeyPropertyName,
|
||||
entityIdentifier,
|
||||
session
|
||||
|
|
|
@ -13,11 +13,9 @@ import org.hibernate.engine.spi.EntityKey;
|
|||
import org.hibernate.engine.spi.EntityUniqueKey;
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.UniqueKeyLoadable;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
|
@ -208,7 +206,7 @@ public class CircularBiDirectionalFetchImpl implements BiDirectionalFetch {
|
|||
);
|
||||
Object entityInstance = persistenceContext.getEntity( euk );
|
||||
if ( entityInstance == null ) {
|
||||
entityInstance = ( (UniqueKeyLoadable) entityPersister ).loadByUniqueKey(
|
||||
entityInstance = entityPersister.loadByUniqueKey(
|
||||
uniqueKeyPropertyName,
|
||||
key,
|
||||
session
|
||||
|
|
Loading…
Reference in New Issue