diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/CodeTemplates.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/CodeTemplates.java
index e4089b499b..cddc79f1cc 100644
--- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/CodeTemplates.java
+++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/CodeTemplates.java
@@ -37,6 +37,8 @@ import net.bytebuddy.implementation.bytecode.member.MethodInvocation;
import net.bytebuddy.implementation.bytecode.member.MethodVariableAccess;
import net.bytebuddy.jar.asm.Opcodes;
+import static org.hibernate.engine.internal.ManagedTypeHelper.asCompositeTracker;
+
class CodeTemplates {
static class SetOwner {
@@ -319,14 +321,14 @@ class CodeTemplates {
@Advice.OnMethodEnter
static void enter(@FieldName String fieldName, @FieldValue Object field) {
if ( field != null ) {
- ( (CompositeTracker) field ).$$_hibernate_clearOwner( fieldName );
+ asCompositeTracker( field ).$$_hibernate_clearOwner( fieldName );
}
}
@Advice.OnMethodExit
static void exit(@Advice.This CompositeOwner self, @FieldName String fieldName, @FieldValue Object field) {
if ( field != null ) {
- ( (CompositeTracker) field ).$$_hibernate_setOwner( fieldName, self );
+ asCompositeTracker( field ).$$_hibernate_setOwner( fieldName, self );
}
self.$$_hibernate_trackChange( fieldName );
}
diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementAsProxyLazinessInterceptor.java b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementAsProxyLazinessInterceptor.java
index 416ce04adb..0925251223 100644
--- a/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementAsProxyLazinessInterceptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementAsProxyLazinessInterceptor.java
@@ -22,6 +22,7 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.CompositeType;
import org.hibernate.type.Type;
+import static org.hibernate.engine.internal.ManagedTypeHelper.asSelfDirtinessTracker;
import static org.hibernate.engine.internal.ManagedTypeHelper.isSelfDirtinessTrackerType;
/**
@@ -280,7 +281,7 @@ public class EnhancementAsProxyLazinessInterceptor extends AbstractLazyLoadInter
}
if ( inLineDirtyChecking ) {
- ( (SelfDirtinessTracker) target ).$$_hibernate_trackChange( attributeName );
+ asSelfDirtinessTracker( target ).$$_hibernate_trackChange( attributeName );
}
}
else {
@@ -293,7 +294,7 @@ public class EnhancementAsProxyLazinessInterceptor extends AbstractLazyLoadInter
}
writtenFieldNames.add( attributeName );
- ( (SelfDirtinessTracker) target ).$$_hibernate_trackChange( attributeName );
+ asSelfDirtinessTracker( target ).$$_hibernate_trackChange( attributeName );
}
return newValue;
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/ManagedTypeHelper.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/ManagedTypeHelper.java
index de4bb6bab1..f6fc6b7f19 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/internal/ManagedTypeHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/ManagedTypeHelper.java
@@ -6,6 +6,8 @@
*/
package org.hibernate.engine.internal;
+import org.hibernate.engine.spi.CompositeOwner;
+import org.hibernate.engine.spi.CompositeTracker;
import org.hibernate.engine.spi.PrimeAmongSecondarySupertypes;
import org.hibernate.engine.spi.Managed;
import org.hibernate.engine.spi.ManagedEntity;
@@ -128,6 +130,29 @@ public final class ManagedTypeHelper {
return false;
}
+ /**
+ * @param entity
+ * @return true if and only if the entity implements {@see CompositeOwner}
+ */
+ public static boolean isCompositeOwner(final Object entity) {
+ if ( entity instanceof PrimeAmongSecondarySupertypes ) {
+ PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) entity;
+ return t.asCompositeOwner() != null;
+ }
+ return false;
+ }
+
+ /**
+ * @param entity
+ * @return true if and only if the entity implements {@see CompositeTracker}
+ */
+ public static boolean isCompositeTracker(final Object entity) {
+ if ( entity instanceof PrimeAmongSecondarySupertypes ) {
+ PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) entity;
+ return t.asCompositeTracker() != null;
+ }
+ return false;
+ }
/**
* Helper to execute an action on an entity, but exclusively if it's implementing the {@see PersistentAttributeInterceptable}
@@ -248,6 +273,43 @@ public final class ManagedTypeHelper {
throw new ClassCastException( "Object of type '" + entity.getClass() + "' can't be cast to ManagedEntity" );
}
+ /**
+ * Cast the object to CompositeTracker
+ * (using this is highly preferrable over a direct cast)
+ * @param entity the entity to cast
+ * @return the same instance after casting
+ * @throws ClassCastException if it's not of the right type
+ */
+ public static CompositeTracker asCompositeTracker(final Object entity) {
+ Objects.requireNonNull( entity );
+ if ( entity instanceof PrimeAmongSecondarySupertypes ) {
+ PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) entity;
+ final CompositeTracker e = t.asCompositeTracker();
+ if ( e != null ) {
+ return e;
+ }
+ }
+ throw new ClassCastException( "Object of type '" + entity.getClass() + "' can't be cast to CompositeTracker" );
+ }
+ /**
+ * Cast the object to CompositeOwner
+ * (using this is highly preferrable over a direct cast)
+ * @param entity the entity to cast
+ * @return the same instance after casting
+ * @throws ClassCastException if it's not of the right type
+ */
+ public static CompositeOwner asCompositeOwner(final Object entity) {
+ Objects.requireNonNull( entity );
+ if ( entity instanceof PrimeAmongSecondarySupertypes ) {
+ PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) entity;
+ final CompositeOwner e = t.asCompositeOwner();
+ if ( e != null ) {
+ return e;
+ }
+ }
+ throw new ClassCastException( "Object of type '" + entity.getClass() + "' can't be cast to CompositeOwner" );
+ }
+
/**
* Cast the object to SelfDirtinessTracker
* (using this is highly preferrable over a direct cast)
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/CompositeOwner.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/CompositeOwner.java
index a16870380e..c7715a893c 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/spi/CompositeOwner.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/CompositeOwner.java
@@ -9,9 +9,15 @@ package org.hibernate.engine.spi;
/**
* @author Ståle W. Pedersen
*/
-public interface CompositeOwner {
+public interface CompositeOwner extends PrimeAmongSecondarySupertypes {
/**
* @param attributeName to be added to the dirty list
*/
void $$_hibernate_trackChange(String attributeName);
+
+ @Override
+ default CompositeOwner asCompositeOwner() {
+ return this;
+ }
+
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/CompositeTracker.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/CompositeTracker.java
index a863774bfb..f15ee45cdd 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/spi/CompositeTracker.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/CompositeTracker.java
@@ -9,9 +9,15 @@ package org.hibernate.engine.spi;
/**
* @author Ståle W. Pedersen
*/
-public interface CompositeTracker {
+public interface CompositeTracker extends PrimeAmongSecondarySupertypes {
void $$_hibernate_setOwner(String name, CompositeOwner tracker);
void $$_hibernate_clearOwner(String name);
+
+ @Override
+ default CompositeTracker asCompositeTracker() {
+ return this;
+ }
+
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/PrimeAmongSecondarySupertypes.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/PrimeAmongSecondarySupertypes.java
index 25e78bbc33..625513c368 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/spi/PrimeAmongSecondarySupertypes.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/PrimeAmongSecondarySupertypes.java
@@ -45,4 +45,12 @@ public interface PrimeAmongSecondarySupertypes {
return null;
}
+ default CompositeOwner asCompositeOwner() {
+ return null;
+ }
+
+ default CompositeTracker asCompositeTracker() {
+ return null;
+ }
+
}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
index 70974a24ab..3153a3d828 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
@@ -273,6 +273,7 @@ import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.MutabilityPlan;
+import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
import static org.hibernate.engine.internal.ManagedTypeHelper.processIfPersistentAttributeInterceptable;
import static org.hibernate.engine.internal.ManagedTypeHelper.processIfSelfDirtinessTracker;
@@ -1370,7 +1371,7 @@ public abstract class AbstractEntityPersister
public Object initializeLazyProperty(String fieldName, Object entity, SharedSessionContractImplementor session) {
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
final EntityEntry entry = persistenceContext.getEntry( entity );
- final PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
+ final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( entity ).$$_hibernate_getInterceptor();
assert interceptor != null : "Expecting bytecode interceptor to be non-null";
if ( hasCollections() ) {
@@ -1494,7 +1495,7 @@ public abstract class AbstractEntityPersister
throw new AssertionFailure( "no lazy properties" );
}
- final PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
+ final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( entity ).$$_hibernate_getInterceptor();
assert interceptor != null : "Expecting bytecode interceptor to be non-null";
LOG.tracef( "Initializing lazy properties from datastore (triggered for `%s`)", fieldName );
diff --git a/hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedSetterImpl.java b/hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedSetterImpl.java
index f68417a2c6..2a706fd695 100644
--- a/hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedSetterImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedSetterImpl.java
@@ -10,12 +10,16 @@ import java.io.Serializable;
import java.lang.reflect.Field;
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
+import org.hibernate.engine.internal.ManagedTypeHelper;
import org.hibernate.engine.spi.CompositeOwner;
import org.hibernate.engine.spi.CompositeTracker;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.property.access.internal.AbstractFieldSerialForm;
+import static org.hibernate.engine.internal.ManagedTypeHelper.asCompositeOwner;
+import static org.hibernate.engine.internal.ManagedTypeHelper.asCompositeTracker;
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
+import static org.hibernate.engine.internal.ManagedTypeHelper.isCompositeTracker;
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptableType;
/**
@@ -49,8 +53,8 @@ public class EnhancedSetterImpl extends SetterFieldImpl {
super.set( target, value );
// This sets the component relation for dirty tracking purposes
- if ( ( enhancementState & COMPOSITE_OWNER ) != 0 && ( ( enhancementState & COMPOSITE_TRACKER_MASK ) != 0 && value != null || value instanceof CompositeTracker ) ) {
- ( (CompositeTracker) value ).$$_hibernate_setOwner( propertyName, (CompositeOwner) target );
+ if ( ( enhancementState & COMPOSITE_OWNER ) != 0 && ( ( enhancementState & COMPOSITE_TRACKER_MASK ) != 0 && value != null || isCompositeTracker( value ) ) ) {
+ asCompositeTracker( value ).$$_hibernate_setOwner( propertyName, asCompositeOwner( target ) );
}
// This marks the attribute as initialized, so it doesn't get lazily loaded afterwards