diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java
index ec5995c039..b4d6a73421 100644
--- a/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java
+++ b/hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java
@@ -17,6 +17,7 @@
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.spi.Status;
+import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.persister.entity.EntityPersister;
/**
@@ -163,13 +164,15 @@ public void afterDeserialize(SharedSessionContractImplementor session) {
*/
protected void handleNaturalIdPreSaveNotifications() {
// before save, we need to add a local (transactional) natural id cross-reference
- getSession().getPersistenceContextInternal().getNaturalIdHelper().manageLocalNaturalIdCrossReference(
- getPersister(),
- getId(),
- state,
- null,
- CachedNaturalIdValueSource.INSERT
- );
+ final NaturalIdMapping naturalIdMapping = getPersister().getNaturalIdMapping();
+ if ( naturalIdMapping != null ) {
+ getSession().getPersistenceContextInternal().getNaturalIdHelper().manageLocalResolution(
+ getId(),
+ naturalIdMapping.extractNaturalIdValues( state, getSession() ),
+ getPersister(),
+ CachedNaturalIdValueSource.INSERT
+ );
+ }
}
/**
@@ -178,23 +181,29 @@ protected void handleNaturalIdPreSaveNotifications() {
* @param generatedId The generated entity identifier
*/
public void handleNaturalIdPostSaveNotifications(Object generatedId) {
+ final NaturalIdMapping naturalIdMapping = getPersister().getNaturalIdMapping();
+ if ( naturalIdMapping == null ) {
+ return;
+ }
+
+ final Object naturalIdValues = naturalIdMapping.extractNaturalIdValues( state, getSession() );
+
final PersistenceContext.NaturalIdHelper naturalIdHelper = getSession().getPersistenceContextInternal().getNaturalIdHelper();
if ( isEarlyInsert() ) {
// with early insert, we still need to add a local (transactional) natural id cross-reference
- naturalIdHelper.manageLocalNaturalIdCrossReference(
- getPersister(),
+ naturalIdHelper.manageLocalResolution(
generatedId,
- state,
- null,
+ naturalIdValues,
+ getPersister(),
CachedNaturalIdValueSource.INSERT
);
}
// after save, we need to manage the shared cache entries
- naturalIdHelper.manageSharedNaturalIdCrossReference(
- getPersister(),
+ naturalIdHelper.manageSharedResolution(
generatedId,
- state,
+ naturalIdValues,
null,
+ getPersister(),
CachedNaturalIdValueSource.INSERT
);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java
index e43efdd349..678ae353e1 100644
--- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java
+++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java
@@ -21,6 +21,7 @@
import org.hibernate.event.spi.PostDeleteEventListener;
import org.hibernate.event.spi.PreDeleteEvent;
import org.hibernate.event.spi.PreDeleteEventListener;
+import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.stat.spi.StatisticsImplementor;
@@ -33,7 +34,9 @@ public class EntityDeleteAction extends EntityAction {
private final Object[] state;
private SoftLock lock;
- private Object[] naturalIdValues;
+
+ private final NaturalIdMapping naturalIdMapping;
+ private Object naturalIdValues;
/**
* Constructs an EntityDeleteAction.
@@ -58,12 +61,15 @@ public EntityDeleteAction(
this.isCascadeDeleteEnabled = isCascadeDeleteEnabled;
this.state = state;
- // before remove we need to remove the local (transactional) natural id cross-reference
- naturalIdValues = session.getPersistenceContextInternal().getNaturalIdHelper().removeLocalNaturalIdCrossReference(
- getPersister(),
- getId(),
- state
- );
+ this.naturalIdMapping = persister.getNaturalIdMapping();
+
+ if ( naturalIdMapping != null ) {
+ naturalIdValues = session.getPersistenceContextInternal().getNaturalIdHelper().removeLocalResolution(
+ getPersister(),
+ getId(),
+ naturalIdMapping.extractNaturalIdValues( state, session )
+ );
+ }
}
public Object getVersion() {
@@ -78,7 +84,7 @@ public Object[] getState() {
return state;
}
- protected Object[] getNaturalIdValues() {
+ protected Object getNaturalIdValues() {
return naturalIdValues;
}
@@ -139,7 +145,7 @@ public void execute() throws HibernateException {
persister.getCacheAccessStrategy().remove( session, ck);
}
- persistenceContext.getNaturalIdHelper().removeSharedNaturalIdCrossReference( persister, id, naturalIdValues );
+ persistenceContext.getNaturalIdHelper().removeSharedResolution( persister, id, naturalIdValues );
postDelete();
diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java
index 509f7b90e1..6bf7c8bf87 100644
--- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java
+++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java
@@ -27,6 +27,7 @@
import org.hibernate.event.spi.PostUpdateEventListener;
import org.hibernate.event.spi.PreUpdateEvent;
import org.hibernate.event.spi.PreUpdateEventListener;
+import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.stat.internal.StatsHelper;
import org.hibernate.stat.spi.StatisticsImplementor;
@@ -42,11 +43,13 @@ public class EntityUpdateAction extends EntityAction {
private final int[] dirtyFields;
private final boolean hasDirtyCollection;
private final Object rowId;
- private final Object[] previousNaturalIdValues;
private Object nextVersion;
private Object cacheEntry;
private SoftLock lock;
+ private final NaturalIdMapping naturalIdMapping;
+ private final Object previousNaturalIdValues;
+
/**
* Constructs an EntityUpdateAction
* @param id The entity identifier
@@ -82,24 +85,23 @@ public EntityUpdateAction(
this.hasDirtyCollection = hasDirtyCollection;
this.rowId = rowId;
- this.previousNaturalIdValues = determinePreviousNaturalIdValues( persister, id, previousState, session );
- session.getPersistenceContextInternal().getNaturalIdHelper().manageLocalNaturalIdCrossReference(
- persister,
- id,
- state,
- previousNaturalIdValues,
- CachedNaturalIdValueSource.UPDATE
- );
+ this.naturalIdMapping = persister.getNaturalIdMapping();
+ if ( naturalIdMapping == null ) {
+ previousNaturalIdValues = null;
+ }
+ else {
+ this.previousNaturalIdValues = determinePreviousNaturalIdValues( persister, id, previousState, session );
+ session.getPersistenceContextInternal().getNaturalIdHelper().manageLocalResolution(
+ id, state, persister,
+ CachedNaturalIdValueSource.UPDATE
+ );
+ }
}
- private Object[] determinePreviousNaturalIdValues(
+ private static Object determinePreviousNaturalIdValues(
EntityPersister persister,
Object id, Object[] previousState,
SharedSessionContractImplementor session) {
- if ( ! persister.hasNaturalIdentifier() ) {
- return null;
- }
-
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
if ( previousState != null ) {
return persistenceContext.getNaturalIdHelper().extractNaturalIdValues( previousState, persister );
@@ -116,50 +118,10 @@ public Object[] getPreviousState() {
return previousState;
}
- public Object getPreviousVersion() {
- return previousVersion;
- }
-
- public Object getNextVersion() {
- return nextVersion;
- }
-
- public void setNextVersion(Object nextVersion) {
- this.nextVersion = nextVersion;
- }
-
- public int[] getDirtyFields() {
- return dirtyFields;
- }
-
- public boolean hasDirtyCollection() {
- return hasDirtyCollection;
- }
-
public Object getRowId() {
return rowId;
}
- public Object[] getPreviousNaturalIdValues() {
- return previousNaturalIdValues;
- }
-
- protected Object getCacheEntry() {
- return cacheEntry;
- }
-
- protected void setCacheEntry(Object cacheEntry) {
- this.cacheEntry = cacheEntry;
- }
-
- protected SoftLock getLock() {
- return lock;
- }
-
- protected void setLock(SoftLock lock) {
- this.lock = lock;
- }
-
@Override
public void execute() throws HibernateException {
final Object id = getId();
@@ -256,13 +218,15 @@ else if ( session.getCacheMode().isPutEnabled() ) {
}
}
- session.getPersistenceContextInternal().getNaturalIdHelper().manageSharedNaturalIdCrossReference(
- persister,
- id,
- state,
- previousNaturalIdValues,
- CachedNaturalIdValueSource.UPDATE
- );
+ if ( naturalIdMapping != null ) {
+ session.getPersistenceContextInternal().getNaturalIdHelper().manageSharedResolution(
+ id,
+ naturalIdMapping.extractNaturalIdValues( state, session ),
+ naturalIdMapping.extractNaturalIdValues( previousState, session ),
+ persister,
+ CachedNaturalIdValueSource.UPDATE
+ );
+ }
postUpdate();
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java
index 432cdf657c..019c7d73dc 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java
@@ -50,7 +50,7 @@ public static Object staticCreateEntityKey(Object id, EntityPersister persister,
return new CacheKeyImplementation( id, persister.getIdentifierType(), persister.getRootEntityName(), tenantIdentifier, factory );
}
- public static Object staticCreateNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
+ public static Object staticCreateNaturalIdKey(Object naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return new NaturalIdCacheKey( naturalIdValues, persister.getPropertyTypes(), persister.getNaturalIdentifierProperties(), persister.getRootEntityName(), session );
}
@@ -62,7 +62,7 @@ public static Object staticGetCollectionId(Object cacheKey) {
return ((CacheKeyImplementation) cacheKey).getId();
}
- public static Object[] staticGetNaturalIdValues(Object cacheKey) {
+ public static Object staticGetNaturalIdValues(Object cacheKey) {
return ((NaturalIdCacheKey) cacheKey).getNaturalIdValues();
}
@@ -77,7 +77,7 @@ public Object createEntityKey(Object id, EntityPersister persister, SessionFacto
}
@Override
- public Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
+ public Object createNaturalIdKey(Object naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return staticCreateNaturalIdKey(naturalIdValues, persister, session);
}
@@ -92,7 +92,7 @@ public Object getCollectionId(Object cacheKey) {
}
@Override
- public Object[] getNaturalIdValues(Object cacheKey) {
+ public Object getNaturalIdValues(Object cacheKey) {
return staticGetNaturalIdValues(cacheKey);
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java
index 2cde6f8db8..d69509616e 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java
@@ -9,13 +9,12 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
-import java.util.Arrays;
import java.util.Objects;
-import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.ValueHolder;
-import org.hibernate.type.EntityType;
+import org.hibernate.metamodel.mapping.EntityMappingType;
+import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.type.Type;
/**
@@ -28,7 +27,7 @@
* @author Steve Ebersole
*/
public class NaturalIdCacheKey implements Serializable {
- private final Object[] naturalIdValues;
+ private final Object naturalIdValues;
private final String entityName;
private final String tenantId;
private final int hashCode;
@@ -43,40 +42,20 @@ public class NaturalIdCacheKey implements Serializable {
* @param session The originating session
*/
public NaturalIdCacheKey(
- final Object[] naturalIdValues,
- Type[] propertyTypes, int[] naturalIdPropertyIndexes, final String entityName,
+ final Object naturalIdValues,
+ Type[] propertyTypes,
+ int[] naturalIdPropertyIndexes,
+ final String entityName,
final SharedSessionContractImplementor session) {
-
this.entityName = entityName;
this.tenantId = session.getTenantIdentifier();
- this.naturalIdValues = new Serializable[naturalIdValues.length];
+ final EntityMappingType entityMappingType = session.getFactory().getRuntimeMetamodels().getEntityMappingType( entityName );
+ final NaturalIdMapping naturalIdMapping = entityMappingType.getNaturalIdMapping();
- final SessionFactoryImplementor factory = session.getFactory();
+ this.naturalIdValues = naturalIdMapping.disassemble( naturalIdValues, session );
+ this.hashCode = naturalIdMapping.calculateHashCode( naturalIdValues, session );
- final int prime = 31;
- int result = 1;
- result = prime * result + ( ( this.entityName == null ) ? 0 : this.entityName.hashCode() );
- result = prime * result + ( ( this.tenantId == null ) ? 0 : this.tenantId.hashCode() );
- for ( int i = 0; i < naturalIdValues.length; i++ ) {
- final int naturalIdPropertyIndex = naturalIdPropertyIndexes[i];
- final Type type = propertyTypes[naturalIdPropertyIndex];
- final Object value = naturalIdValues[i];
-
- result = prime * result + (value != null ? type.getHashCode( value, factory ) : 0);
-
- // The natural id may not be fully resolved in some situations. See HHH-7513 for one of them
- // (re-attaching a mutable natural id uses a database snapshot and hydration does not resolve associations).
- // TODO: The snapshot should probably be revisited at some point. Consider semi-resolving, hydrating, etc.
- if (type instanceof EntityType && type.getSemiResolvedType( factory ).getReturnedClass().isInstance( value )) {
- this.naturalIdValues[i] = value;
- }
- else {
- this.naturalIdValues[i] = type.disassemble( value, session, null );
- }
- }
-
- this.hashCode = result;
initTransients();
}
@@ -87,15 +66,20 @@ private void initTransients() {
public String initialize() {
//Complex toString is needed as naturalIds for entities are not simply based on a single value like primary keys
//the only same way to differentiate the keys is to include the disassembled values in the string.
- final StringBuilder toStringBuilder = new StringBuilder().append( entityName ).append(
- "##NaturalId[" );
- for ( int i = 0; i < naturalIdValues.length; i++ ) {
- toStringBuilder.append( naturalIdValues[i] );
- if ( i + 1 < naturalIdValues.length ) {
- toStringBuilder.append( ", " );
+ final StringBuilder toStringBuilder = new StringBuilder()
+ .append( entityName ).append( "##NaturalId[" );
+ if ( naturalIdValues instanceof Object[] ) {
+ final Object[] values = (Object[]) naturalIdValues;
+ for ( int i = 0; i < values.length; i++ ) {
+ toStringBuilder.append( values[ i ] );
+ if ( i + 1 < values.length ) {
+ toStringBuilder.append( ", " );
+ }
}
}
- toStringBuilder.append( "]" );
+ else {
+ toStringBuilder.append( naturalIdValues );
+ }
return toStringBuilder.toString();
}
@@ -114,7 +98,7 @@ public String getTenantId() {
}
@SuppressWarnings( {"UnusedDeclaration"})
- public Object[] getNaturalIdValues() {
+ public Object getNaturalIdValues() {
return naturalIdValues;
}
@@ -145,7 +129,7 @@ public boolean equals(Object o) {
final NaturalIdCacheKey other = (NaturalIdCacheKey) o;
return Objects.equals( entityName, other.entityName )
&& Objects.equals( tenantId, other.tenantId )
- && Arrays.deepEquals( this.naturalIdValues, other.naturalIdValues );
+ && Objects.deepEquals( this.naturalIdValues, other.naturalIdValues );
}
private void readObject(ObjectInputStream ois)
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java
index f5e68f899f..f865c935bb 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java
@@ -32,7 +32,7 @@ public Object createEntityKey(Object id, EntityPersister persister, SessionFacto
}
@Override
- public Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
+ public Object createNaturalIdKey(Object naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
// natural ids always need to be wrapped
return new NaturalIdCacheKey(naturalIdValues, persister.getPropertyTypes(), persister.getNaturalIdentifierProperties(), null, session);
}
@@ -48,7 +48,7 @@ public Object getCollectionId(Object cacheKey) {
}
@Override
- public Object[] getNaturalIdValues(Object cacheKey) {
+ public Object getNaturalIdValues(Object cacheKey) {
return ((NaturalIdCacheKey) cacheKey).getNaturalIdValues();
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java
index aed351801a..e6fd770669 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java
@@ -19,11 +19,11 @@ public interface CacheKeysFactory {
Object createEntityKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier);
- Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session);
+ Object createNaturalIdKey(Object naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session);
Object getEntityId(Object cacheKey);
Object getCollectionId(Object cacheKey);
- Object[] getNaturalIdValues(Object cacheKey);
+ Object getNaturalIdValues(Object cacheKey);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdDataAccess.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdDataAccess.java
index 5c6b7fd18d..65bf6c465b 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdDataAccess.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdDataAccess.java
@@ -47,7 +47,7 @@ public interface NaturalIdDataAccess extends CachedDomainDataAccess {
* @return a key which can be used to identify an element unequivocally on this same region
*/
Object generateCacheKey(
- Object[] naturalIdValues,
+ Object naturalIdValues,
EntityPersister rootEntityDescriptor,
SharedSessionContractImplementor session);
@@ -58,7 +58,7 @@ Object generateCacheKey(
*
* @return the sequence of values which unequivocally identifies a cached element on this region
*/
- Object[] getNaturalIdValues(Object cacheKey);
+ Object getNaturalIdValues(Object cacheKey);
/**
* Called afterQuery an item has been inserted (beforeQuery the transaction completes),
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractNaturalIdDataAccess.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractNaturalIdDataAccess.java
index 292e7c85a4..8b84cfaca3 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractNaturalIdDataAccess.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractNaturalIdDataAccess.java
@@ -31,14 +31,14 @@ public AbstractNaturalIdDataAccess(
@Override
public Object generateCacheKey(
- Object[] naturalIdValues,
+ Object naturalIdValues,
EntityPersister persister,
SharedSessionContractImplementor session) {
return keysFactory.createNaturalIdKey( naturalIdValues, persister, session );
}
@Override
- public Object[] getNaturalIdValues(Object cacheKey) {
+ public Object getNaturalIdValues(Object cacheKey) {
return keysFactory.getNaturalIdValues( cacheKey );
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdReadWriteAccess.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdReadWriteAccess.java
index f6e553458c..b4f53f4297 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdReadWriteAccess.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdReadWriteAccess.java
@@ -53,14 +53,14 @@ protected Comparator getVersionComparator() {
@Override
public Object generateCacheKey(
- Object[] naturalIdValues,
+ Object naturalIdValues,
EntityPersister rootEntityDescriptor,
SharedSessionContractImplementor session) {
return keysFactory.createNaturalIdKey( naturalIdValues, rootEntityDescriptor, session );
}
@Override
- public Object[] getNaturalIdValues(Object cacheKey) {
+ public Object getNaturalIdValues(Object cacheKey) {
return keysFactory.getNaturalIdValues( cacheKey );
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/AbstractEntityEntry.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/AbstractEntityEntry.java
index a23b50d914..c6ebab8430 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/internal/AbstractEntityEntry.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/AbstractEntityEntry.java
@@ -408,11 +408,8 @@ public void setReadOnly(boolean readOnly, Object entity) {
}
setStatus( Status.MANAGED );
loadedState = getPersister().getPropertyValues( entity );
- getPersistenceContext().getNaturalIdHelper().manageLocalNaturalIdCrossReference(
- persister,
- id,
- loadedState,
- null,
+ getPersistenceContext().getNaturalIdHelper().manageLocalResolution(
+ id, loadedState, persister,
CachedNaturalIdValueSource.LOAD
);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java
index e8b9d1d066..db930873e3 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java
@@ -8,7 +8,6 @@
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -19,10 +18,10 @@
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
+import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.stat.internal.StatsHelper;
import org.hibernate.stat.spi.StatisticsImplementor;
-import org.hibernate.type.Type;
import org.jboss.logging.Logger;
@@ -70,12 +69,12 @@ protected SharedSessionContractImplementor session() {
*
* @return {@code true} if a new entry was actually added; {@code false} otherwise.
*/
- public boolean cacheNaturalIdCrossReference(EntityPersister persister, Object pk, Object[] naturalIdValues) {
+ public boolean cacheResolution(EntityPersister persister, Object pk, Object naturalIdValues) {
validateNaturalId( persister, naturalIdValues );
NaturalIdResolutionCache entityNaturalIdResolutionCache = naturalIdResolutionCacheMap.get( persister );
if ( entityNaturalIdResolutionCache == null ) {
- entityNaturalIdResolutionCache = new NaturalIdResolutionCache( persister );
+ entityNaturalIdResolutionCache = new NaturalIdResolutionCache( persister, persistenceContext );
NaturalIdResolutionCache previousInstance = naturalIdResolutionCacheMap.putIfAbsent( persister, entityNaturalIdResolutionCache );
if ( previousInstance != null ) {
entityNaturalIdResolutionCache = previousInstance;
@@ -93,29 +92,29 @@ public boolean cacheNaturalIdCrossReference(EntityPersister persister, Object pk
*
* @return The cached values, if any. May be different from incoming values.
*/
- public Object[] removeNaturalIdCrossReference(EntityPersister persister, Object pk, Object[] naturalIdValues) {
+ public Object removeResolutions(EntityPersister persister, Object pk, Object naturalIdValues) {
persister = locatePersisterForKey( persister );
+
+ final NaturalIdMapping naturalIdMapping = persister.getNaturalIdMapping();
validateNaturalId( persister, naturalIdValues );
final NaturalIdResolutionCache entityNaturalIdResolutionCache = naturalIdResolutionCacheMap.get( persister );
- Object[] sessionCachedNaturalIdValues = null;
+ Object sessionCachedNaturalIdValues = null;
if ( entityNaturalIdResolutionCache != null ) {
- final CachedNaturalId cachedNaturalId = entityNaturalIdResolutionCache.pkToNaturalIdMap
- .remove( pk );
+ final CachedNaturalId cachedNaturalId = entityNaturalIdResolutionCache.pkToNaturalIdMap.remove( pk );
if ( cachedNaturalId != null ) {
entityNaturalIdResolutionCache.naturalIdToPkMap.remove( cachedNaturalId );
- sessionCachedNaturalIdValues = cachedNaturalId.getValues();
+ sessionCachedNaturalIdValues = cachedNaturalId.getNaturalId();
}
}
if ( persister.hasNaturalIdCache() ) {
- final NaturalIdDataAccess naturalIdCacheAccessStrategy = persister
- .getNaturalIdCacheAccessStrategy();
+ final NaturalIdDataAccess naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy();
final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session() );
naturalIdCacheAccessStrategy.evict( naturalIdCacheKey );
if ( sessionCachedNaturalIdValues != null
- && !Arrays.equals( sessionCachedNaturalIdValues, naturalIdValues ) ) {
+ && ! naturalIdMapping.areEqual( sessionCachedNaturalIdValues, naturalIdValues, session() ) ) {
final Object sessionNaturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( sessionCachedNaturalIdValues, persister, session() );
naturalIdCacheAccessStrategy.evict( sessionNaturalIdCacheKey );
}
@@ -133,7 +132,7 @@ public Object[] removeNaturalIdCrossReference(EntityPersister persister, Object
*
* @return {@code true} if the given naturalIdValues match the current cached values; {@code false} otherwise.
*/
- public boolean sameAsCached(EntityPersister persister, Object pk, Object[] naturalIdValues) {
+ public boolean sameAsCached(EntityPersister persister, Object pk, Object naturalIdValues) {
final NaturalIdResolutionCache entityNaturalIdResolutionCache = naturalIdResolutionCacheMap.get( persister );
return entityNaturalIdResolutionCache != null
&& entityNaturalIdResolutionCache.sameAsCached( pk, naturalIdValues );
@@ -157,16 +156,17 @@ protected EntityPersister locatePersisterForKey(EntityPersister persister) {
*
the number of natural id values matches the expected number
*
*
- * @param persister The persister representing the entity type.
+ * @param entityDescriptor The entity type descriptor
* @param naturalIdValues The natural id values
*/
- protected void validateNaturalId(EntityPersister persister, Object[] naturalIdValues) {
- if ( !persister.hasNaturalIdentifier() ) {
+ protected void validateNaturalId(EntityPersister entityDescriptor, Object naturalIdValues) {
+ final NaturalIdMapping naturalIdMapping = entityDescriptor.getNaturalIdMapping();
+
+ if ( naturalIdMapping == null ) {
throw new IllegalArgumentException( "Entity did not define a natural-id" );
}
- if ( persister.getNaturalIdentifierProperties().length != naturalIdValues.length ) {
- throw new IllegalArgumentException( "Mismatch between expected number of natural-id values and found." );
- }
+
+ naturalIdMapping.validateInternalForm( naturalIdValues, persistenceContext.getSession() );
}
/**
@@ -177,7 +177,7 @@ protected void validateNaturalId(EntityPersister persister, Object[] naturalIdVa
*
* @return The corresponding cross-referenced natural id values, or {@code null} if none
*/
- public Object[] findCachedNaturalId(EntityPersister persister, Object pk) {
+ public Object findCachedNaturalId(EntityPersister persister, Object pk) {
persister = locatePersisterForKey( persister );
final NaturalIdResolutionCache entityNaturalIdResolutionCache = naturalIdResolutionCacheMap.get( persister );
if ( entityNaturalIdResolutionCache == null ) {
@@ -189,7 +189,7 @@ public Object[] findCachedNaturalId(EntityPersister persister, Object pk) {
return null;
}
- return cachedNaturalId.getValues();
+ return cachedNaturalId.getNaturalId();
}
/**
@@ -199,19 +199,19 @@ public Object[] findCachedNaturalId(EntityPersister persister, Object pk) {
*
* @param persister The persister representing the entity type.
* @param naturalIdValues The natural id value(s)
- *
- * @return The corresponding cross-referenced primary key,
+ *
+ * @return The corresponding cross-referenced primary key,
* {@link PersistenceContext.NaturalIdHelper#INVALID_NATURAL_ID_REFERENCE},
* or {@code null} if none
*/
- public Object findCachedNaturalIdResolution(EntityPersister persister, Object[] naturalIdValues) {
+ public Object findResolution(EntityPersister persister, Object naturalIdValues) {
persister = locatePersisterForKey( persister );
validateNaturalId( persister, naturalIdValues );
NaturalIdResolutionCache entityNaturalIdResolutionCache = naturalIdResolutionCacheMap.get( persister );
Object pk;
- final CachedNaturalId cachedNaturalId = new CachedNaturalId( persister, naturalIdValues );
+ final CachedNaturalId cachedNaturalId = new CachedNaturalId( naturalIdValues, persister, persistenceContext );
if ( entityNaturalIdResolutionCache != null ) {
pk = entityNaturalIdResolutionCache.naturalIdToPkMap.get( cachedNaturalId );
@@ -221,7 +221,7 @@ public Object findCachedNaturalIdResolution(EntityPersister persister, Object[]
LOG.trace(
"Resolved natural key -> primary key resolution in session cache: " +
persister.getRootEntityName() + "#[" +
- Arrays.toString( naturalIdValues ) + "]"
+ naturalIdValues + "]"
);
}
@@ -264,14 +264,14 @@ public Object findCachedNaturalIdResolution(EntityPersister persister, Object[]
// protected to avoid Arrays.toString call unless needed
LOG.tracef(
"Found natural key [%s] -> primary key [%s] xref in second-level cache for %s",
- Arrays.toString( naturalIdValues ),
+ naturalIdValues,
pk,
persister.getRootEntityName()
);
}
if ( entityNaturalIdResolutionCache == null ) {
- entityNaturalIdResolutionCache = new NaturalIdResolutionCache( persister );
+ entityNaturalIdResolutionCache = new NaturalIdResolutionCache( persister, persistenceContext );
NaturalIdResolutionCache existingCache = naturalIdResolutionCacheMap.putIfAbsent( persister, entityNaturalIdResolutionCache );
if ( existingCache != null ) {
entityNaturalIdResolutionCache = existingCache;
@@ -329,7 +329,7 @@ public Collection