raft of minor code cleanups

This commit is contained in:
Gavin 2023-05-20 12:10:36 +02:00 committed by Gavin King
parent 4247f7b155
commit fb28443081
6 changed files with 90 additions and 104 deletions

View File

@ -37,15 +37,16 @@ import org.hibernate.collection.spi.LazyInitializable;
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable; import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable; import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
/** /**
* Various utility functions for working with proxies and lazy collection references. * Various utility functions for working with proxies and lazy collection references.
* <p> * <p>
* Operations like {@link #isInitialized(Object)} and {@link #initialize(Object)} are * Operations like {@link #isInitialized(Object)} and {@link #initialize(Object)} are
* of general purpose. But {@link #createDetachedProxy(SessionFactory, Class, Object)} * of general purpose. But {@link #createDetachedProxy(SessionFactory, Class, Object)}
* and {@link CollectionInterface#createDetachedProxy(SessionFactory, Class, Object)} * and {@link CollectionInterface#createDetachedInstance()} are intended for use by
* are intended for use by generic code that must materialize an "amputated" graph of * generic code that must materialize an "amputated" graph of Hibernate entities.
* Hibernate entities. (For example, a library which deserializes entities from JSON.) * (For example, a library which deserializes entities from JSON.)
* <p> * <p>
* Lazy fetching of a {@linkplain jakarta.persistence.OneToOne one to one} or * Lazy fetching of a {@linkplain jakarta.persistence.OneToOne one to one} or
* {@linkplain jakarta.persistence.ManyToOne many to one} association requires special * {@linkplain jakarta.persistence.ManyToOne many to one} association requires special
@ -126,7 +127,7 @@ public final class Hibernate {
return; return;
} }
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxy ); final LazyInitializer lazyInitializer = extractLazyInitializer( proxy );
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
lazyInitializer.initialize(); lazyInitializer.initialize();
} }
@ -134,7 +135,8 @@ public final class Hibernate {
( (LazyInitializable) proxy ).forceInitialization(); ( (LazyInitializable) proxy ).forceInitialization();
} }
else if ( isPersistentAttributeInterceptable( proxy ) ) { else if ( isPersistentAttributeInterceptable( proxy ) ) {
final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( proxy ).$$_hibernate_getInterceptor(); final PersistentAttributeInterceptor interceptor =
asPersistentAttributeInterceptable( proxy ).$$_hibernate_getInterceptor();
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) { if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
( (EnhancementAsProxyLazinessInterceptor) interceptor ).forceInitialize( proxy, null ); ( (EnhancementAsProxyLazinessInterceptor) interceptor ).forceInitialize( proxy, null );
} }
@ -150,12 +152,13 @@ public final class Hibernate {
* @return true if the argument is already initialized, or is not a proxy or collection * @return true if the argument is already initialized, or is not a proxy or collection
*/ */
public static boolean isInitialized(Object proxy) { public static boolean isInitialized(Object proxy) {
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxy ); final LazyInitializer lazyInitializer = extractLazyInitializer( proxy );
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
return !lazyInitializer.isUninitialized(); return !lazyInitializer.isUninitialized();
} }
else if ( isPersistentAttributeInterceptable( proxy ) ) { else if ( isPersistentAttributeInterceptable( proxy ) ) {
final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( proxy ).$$_hibernate_getInterceptor(); final PersistentAttributeInterceptor interceptor =
asPersistentAttributeInterceptable( proxy ).$$_hibernate_getInterceptor();
if (interceptor instanceof EnhancementAsProxyLazinessInterceptor) { if (interceptor instanceof EnhancementAsProxyLazinessInterceptor) {
return ( (EnhancementAsProxyLazinessInterceptor) interceptor ).isInitialized(); return ( (EnhancementAsProxyLazinessInterceptor) interceptor ).isInitialized();
} }
@ -294,7 +297,7 @@ public final class Hibernate {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> Class<? extends T> getClass(T proxy) { public static <T> Class<? extends T> getClass(T proxy) {
Class<?> result; Class<?> result;
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxy ); final LazyInitializer lazyInitializer = extractLazyInitializer( proxy );
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
result = lazyInitializer result = lazyInitializer
.getImplementation() .getImplementation()
@ -334,7 +337,7 @@ public final class Hibernate {
*/ */
public static boolean isPropertyInitialized(Object proxy, String propertyName) { public static boolean isPropertyInitialized(Object proxy, String propertyName) {
final Object entity; final Object entity;
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxy ); final LazyInitializer lazyInitializer = extractLazyInitializer( proxy );
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
if ( lazyInitializer.isUninitialized() ) { if ( lazyInitializer.isUninitialized() ) {
return false; return false;
@ -369,7 +372,7 @@ public final class Hibernate {
* uninitialized proxy that is not associated with an open session. * uninitialized proxy that is not associated with an open session.
*/ */
public static Object unproxy(Object proxy) { public static Object unproxy(Object proxy) {
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxy ); final LazyInitializer lazyInitializer = extractLazyInitializer( proxy );
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
return lazyInitializer.getImplementation(); return lazyInitializer.getImplementation();
} }
@ -397,7 +400,7 @@ public final class Hibernate {
/** /**
* Obtain a detached, uninitialized reference (a proxy) for a persistent entity with * Obtain a detached, uninitialized reference (a proxy) for a persistent entity with
* the given identifier. * the given identifier.
* * <p>
* The returned proxy is not associated with any session, and cannot be initialized * The returned proxy is not associated with any session, and cannot be initialized
* by calling {@link #initialize(Object)}. It can be used to represent a reference to * by calling {@link #initialize(Object)}. It can be used to represent a reference to
* the entity when working with a detached object graph. * the entity when working with a detached object graph.
@ -441,7 +444,7 @@ public final class Hibernate {
/** /**
* Obtain a detached, uninitialized persistent collection of the type represented * Obtain a detached, uninitialized persistent collection of the type represented
* by this object. * by this object.
* * <p>
* The returned wrapper object is not associated with any session, and cannot be * The returned wrapper object is not associated with any session, and cannot be
* initialized by calling {@link #initialize(Object)}. It can be used to represent * initialized by calling {@link #initialize(Object)}. It can be used to represent
* an uninitialized collection when working with a detached object graph. * an uninitialized collection when working with a detached object graph.

View File

@ -189,8 +189,8 @@ public class HibernatePersistenceProvider implements PersistenceProvider {
return PersistenceUtilHelper.isLoadedWithReference( proxy, property, cache ); return PersistenceUtilHelper.isLoadedWithReference( proxy, property, cache );
} }
@Override @Override
public LoadState isLoaded(Object o) { public LoadState isLoaded(Object object) {
return PersistenceUtilHelper.isLoaded(o); return PersistenceUtilHelper.getLoadState( object );
} }
}; };

View File

@ -8,7 +8,6 @@ package org.hibernate.jpa.internal;
import java.io.Serializable; import java.io.Serializable;
import jakarta.persistence.PersistenceUnitUtil; import jakarta.persistence.PersistenceUnitUtil;
import jakarta.persistence.spi.LoadState;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.MappingException; import org.hibernate.MappingException;
@ -16,13 +15,17 @@ import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jpa.internal.util.PersistenceUtilHelper; import org.hibernate.jpa.internal.util.PersistenceUtilHelper;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer; import org.hibernate.proxy.LazyInitializer;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import static jakarta.persistence.spi.LoadState.NOT_LOADED;
import static org.hibernate.engine.internal.ManagedTypeHelper.asManagedEntity; import static org.hibernate.engine.internal.ManagedTypeHelper.asManagedEntity;
import static org.hibernate.engine.internal.ManagedTypeHelper.isManagedEntity; import static org.hibernate.engine.internal.ManagedTypeHelper.isManagedEntity;
import static org.hibernate.jpa.internal.util.PersistenceUtilHelper.getLoadState;
import static org.hibernate.jpa.internal.util.PersistenceUtilHelper.isLoadedWithReference;
import static org.hibernate.jpa.internal.util.PersistenceUtilHelper.isLoadedWithoutReference;
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -41,19 +44,13 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
public boolean isLoaded(Object entity, String attributeName) { public boolean isLoaded(Object entity, String attributeName) {
// added log message to help with HHH-7454, if state == LoadState,NOT_LOADED, returning true or false is not accurate. // added log message to help with HHH-7454, if state == LoadState,NOT_LOADED, returning true or false is not accurate.
log.debug( "PersistenceUnitUtil#isLoaded is not always accurate; consider using EntityManager#contains instead" ); log.debug( "PersistenceUnitUtil#isLoaded is not always accurate; consider using EntityManager#contains instead" );
LoadState state = PersistenceUtilHelper.isLoadedWithoutReference( entity, attributeName, cache ); switch ( isLoadedWithoutReference( entity, attributeName, cache ) ) {
if ( state == LoadState.LOADED ) { case LOADED:
return true; return true;
} case NOT_LOADED:
else if ( state == LoadState.NOT_LOADED ) { return false;
return false; default:
} return isLoadedWithReference( entity, attributeName, cache ) != NOT_LOADED;
else {
return PersistenceUtilHelper.isLoadedWithReference(
entity,
attributeName,
cache
) != LoadState.NOT_LOADED;
} }
} }
@ -61,7 +58,7 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
public boolean isLoaded(Object entity) { public boolean isLoaded(Object entity) {
// added log message to help with HHH-7454, if state == LoadState,NOT_LOADED, returning true or false is not accurate. // added log message to help with HHH-7454, if state == LoadState,NOT_LOADED, returning true or false is not accurate.
log.debug( "PersistenceUnitUtil#isLoaded is not always accurate; consider using EntityManager#contains instead" ); log.debug( "PersistenceUnitUtil#isLoaded is not always accurate; consider using EntityManager#contains instead" );
return PersistenceUtilHelper.isLoaded( entity ) != LoadState.NOT_LOADED; return getLoadState( entity ) != NOT_LOADED;
} }
@Override @Override
@ -70,12 +67,12 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
throw new IllegalArgumentException( "Passed entity cannot be null" ); throw new IllegalArgumentException( "Passed entity cannot be null" );
} }
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity ); final LazyInitializer lazyInitializer = extractLazyInitializer( entity );
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
return lazyInitializer.getInternalIdentifier(); return lazyInitializer.getInternalIdentifier();
} }
else if ( isManagedEntity( entity ) ) { else if ( isManagedEntity( entity ) ) {
EntityEntry entityEntry = asManagedEntity( entity ).$$_hibernate_getEntityEntry(); final EntityEntry entityEntry = asManagedEntity( entity ).$$_hibernate_getEntityEntry();
if ( entityEntry != null ) { if ( entityEntry != null ) {
return entityEntry.getId(); return entityEntry.getId();
} }
@ -96,7 +93,7 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
} }
private Object getIdentifierFromPersister(Object entity) { private Object getIdentifierFromPersister(Object entity) {
Class<?> entityClass = Hibernate.getClass( entity ); final Class<?> entityClass = Hibernate.getClass( entity );
final EntityPersister persister; final EntityPersister persister;
try { try {
persister = sessionFactory.getRuntimeMetamodels() persister = sessionFactory.getRuntimeMetamodels()

View File

@ -11,7 +11,6 @@ import java.io.Serializable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -23,6 +22,7 @@ import jakarta.persistence.spi.LoadState;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor; import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor; import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
import org.hibernate.collection.spi.LazyInitializable;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.PersistentAttributeInterceptable; import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
@ -30,8 +30,13 @@ import org.hibernate.internal.util.securitymanager.SystemSecurityManager;
import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer; import org.hibernate.proxy.LazyInitializer;
import static jakarta.persistence.spi.LoadState.LOADED;
import static jakarta.persistence.spi.LoadState.NOT_LOADED;
import static jakarta.persistence.spi.LoadState.UNKNOWN;
import static java.security.AccessController.doPrivileged;
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable; import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable; import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
/** /**
* Central delegate for handling calls from:<ul> * Central delegate for handling calls from:<ul>
@ -80,28 +85,25 @@ public final class PersistenceUtilHelper {
* *
* @return The appropriate LoadState (see above) * @return The appropriate LoadState (see above)
*/ */
public static LoadState isLoaded(Object reference) { public static LoadState getLoadState(Object reference) {
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( reference ); final LazyInitializer lazyInitializer = extractLazyInitializer( reference );
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
final boolean isInitialized = !lazyInitializer.isUninitialized(); return !lazyInitializer.isUninitialized() ? LOADED : NOT_LOADED;
return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
} }
else if ( isPersistentAttributeInterceptable( reference ) ) { else if ( isPersistentAttributeInterceptable( reference ) ) {
boolean isInitialized = isInitialized( asPersistentAttributeInterceptable( reference ) ); return isInitialized( asPersistentAttributeInterceptable( reference ) ) ? LOADED : NOT_LOADED;
return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
} }
else if ( reference instanceof PersistentCollection ) { else if ( reference instanceof LazyInitializable) {
final boolean isInitialized = ( (PersistentCollection<?>) reference ).wasInitialized(); return ( (LazyInitializable) reference ).wasInitialized() ? LOADED : NOT_LOADED;
return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
} }
else { else {
return LoadState.UNKNOWN; return UNKNOWN;
} }
} }
private static boolean isInitialized(PersistentAttributeInterceptable interceptable) { private static boolean isInitialized(PersistentAttributeInterceptable interceptable) {
final BytecodeLazyAttributeInterceptor interceptor = extractInterceptor( interceptable ); final BytecodeLazyAttributeInterceptor interceptor = extractInterceptor( interceptable );
return interceptable == null || interceptor == null || !interceptor.hasAnyUninitializedAttributes(); return interceptor == null || !interceptor.hasAnyUninitializedAttributes();
} }
private static BytecodeLazyAttributeInterceptor extractInterceptor(PersistentAttributeInterceptable interceptable) { private static BytecodeLazyAttributeInterceptor extractInterceptor(PersistentAttributeInterceptable interceptable) {
@ -120,11 +122,11 @@ public final class PersistenceUtilHelper {
*/ */
public static LoadState isLoadedWithoutReference(Object entity, String attributeName, MetadataCache cache) { public static LoadState isLoadedWithoutReference(Object entity, String attributeName, MetadataCache cache) {
boolean sureFromUs = false; boolean sureFromUs = false;
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity ); final LazyInitializer lazyInitializer = extractLazyInitializer( entity );
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
if ( lazyInitializer.isUninitialized() ) { if ( lazyInitializer.isUninitialized() ) {
// we have an uninitialized proxy, the attribute cannot be loaded // we have an uninitialized proxy, the attribute cannot be loaded
return LoadState.NOT_LOADED; return NOT_LOADED;
} }
else { else {
// swap the proxy with target (for proper class name resolution) // swap the proxy with target (for proper class name resolution)
@ -133,7 +135,7 @@ public final class PersistenceUtilHelper {
sureFromUs = true; sureFromUs = true;
} }
// we are instrumenting but we can't assume we are the only ones // we are instrumenting, but we can't assume we are the only ones
if ( isPersistentAttributeInterceptable( entity ) ) { if ( isPersistentAttributeInterceptable( entity ) ) {
final BytecodeLazyAttributeInterceptor interceptor = extractInterceptor( asPersistentAttributeInterceptable( entity ) ); final BytecodeLazyAttributeInterceptor interceptor = extractInterceptor( asPersistentAttributeInterceptable( entity ) );
final boolean isInitialized = interceptor == null || interceptor.isAttributeLoaded( attributeName ); final boolean isInitialized = interceptor == null || interceptor.isAttributeLoaded( attributeName );
@ -142,55 +144,44 @@ public final class PersistenceUtilHelper {
// attributeName is loaded according to bytecode enhancement, but is it loaded as far as association? // attributeName is loaded according to bytecode enhancement, but is it loaded as far as association?
// it's ours, we can read // it's ours, we can read
try { try {
final Class entityClass = entity.getClass(); state = getLoadState( getAttributeValue( entity, attributeName, cache ) );
final Object attributeValue = cache.getClassMetadata( entityClass )
.getAttributeAccess( attributeName )
.extractValue( entity );
state = isLoaded( attributeValue );
// it's ours so we know it's loaded // it's ours so we know it's loaded
if ( state == LoadState.UNKNOWN ) { if ( state == UNKNOWN ) {
state = LoadState.LOADED; state = LOADED;
} }
} }
catch (AttributeExtractionException ignore) { catch (AttributeExtractionException ignore) {
state = LoadState.UNKNOWN; state = UNKNOWN;
} }
} }
else if ( interceptor != null ) { else if ( interceptor != null ) {
state = LoadState.NOT_LOADED; state = NOT_LOADED;
} }
else if ( sureFromUs ) { else if ( sureFromUs ) {
// property is loaded according to bytecode enhancement, but is it loaded as far as association? // property is loaded according to bytecode enhancement, but is it loaded as far as association?
// it's ours, we can read // it's ours, we can read
try { try {
final Class entityClass = entity.getClass(); state = getLoadState( getAttributeValue( entity, attributeName, cache ) );
final Object attributeValue = cache.getClassMetadata( entityClass )
.getAttributeAccess( attributeName )
.extractValue( entity );
state = isLoaded( attributeValue );
// it's ours so we know it's loaded // it's ours so we know it's loaded
if ( state == LoadState.UNKNOWN ) { if ( state == UNKNOWN ) {
state = LoadState.LOADED; state = LOADED;
} }
} }
catch (AttributeExtractionException ignore) { catch (AttributeExtractionException ignore) {
state = LoadState.UNKNOWN; state = UNKNOWN;
} }
} }
else { else {
state = LoadState.UNKNOWN; state = UNKNOWN;
} }
return state; return state;
} }
else { else {
return LoadState.UNKNOWN; return UNKNOWN;
} }
} }
/** /**
* Is the given attribute (by name) loaded? This form must take care to not access the attribute (trigger * Is the given attribute (by name) loaded? This form must take care to not access the attribute (trigger
* initialization). * initialization).
@ -202,11 +193,11 @@ public final class PersistenceUtilHelper {
* @return The LoadState * @return The LoadState
*/ */
public static LoadState isLoadedWithReference(Object entity, String attributeName, MetadataCache cache) { public static LoadState isLoadedWithReference(Object entity, String attributeName, MetadataCache cache) {
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity ); final LazyInitializer lazyInitializer = extractLazyInitializer( entity );
if ( lazyInitializer != null ) { if ( lazyInitializer != null ) {
if ( lazyInitializer.isUninitialized() ) { if ( lazyInitializer.isUninitialized() ) {
// we have an uninitialized proxy, the attribute cannot be loaded // we have an uninitialized proxy, the attribute cannot be loaded
return LoadState.NOT_LOADED; return NOT_LOADED;
} }
else { else {
// swap the proxy with target (for proper class name resolution) // swap the proxy with target (for proper class name resolution)
@ -215,17 +206,18 @@ public final class PersistenceUtilHelper {
} }
try { try {
final Class entityClass = entity.getClass(); return getLoadState( getAttributeValue( entity, attributeName, cache ) );
final Object attributeValue = cache.getClassMetadata( entityClass )
.getAttributeAccess( attributeName )
.extractValue( entity );
return isLoaded( attributeValue );
} }
catch (AttributeExtractionException ignore) { catch (AttributeExtractionException ignore) {
return LoadState.UNKNOWN; return UNKNOWN;
} }
} }
private static Object getAttributeValue(Object entity, String attributeName, MetadataCache cache) {
return cache.getClassMetadata( entity.getClass() )
.getAttributeAccess( attributeName )
.extractValue( entity );
}
public static class AttributeExtractionException extends HibernateException { public static class AttributeExtractionException extends HibernateException {
public AttributeExtractionException(String message) { public AttributeExtractionException(String message) {
@ -316,10 +308,10 @@ public final class PersistenceUtilHelper {
} }
private static class NoSuchAttributeAccess implements AttributeAccess { private static class NoSuchAttributeAccess implements AttributeAccess {
private final Class clazz; private final Class<?> clazz;
private final String attributeName; private final String attributeName;
public NoSuchAttributeAccess(Class clazz, String attributeName) { public NoSuchAttributeAccess(Class<?> clazz, String attributeName) {
this.clazz = clazz; this.clazz = clazz;
this.attributeName = attributeName; this.attributeName = attributeName;
} }
@ -331,9 +323,9 @@ public final class PersistenceUtilHelper {
} }
public static class ClassMetadataCache { public static class ClassMetadataCache {
private final Class specifiedClass; private final Class<?> specifiedClass;
private List<Class<?>> classHierarchy; private final List<Class<?>> classHierarchy;
private Map<String, AttributeAccess> attributeAccessMap = new HashMap<>(); private final Map<String, AttributeAccess> attributeAccessMap = new HashMap<>();
public ClassMetadataCache(Class<?> clazz) { public ClassMetadataCache(Class<?> clazz) {
this.specifiedClass = clazz; this.specifiedClass = clazz;
@ -361,28 +353,22 @@ public final class PersistenceUtilHelper {
} }
private AttributeAccess buildAttributeAccess(final String attributeName) { private AttributeAccess buildAttributeAccess(final String attributeName) {
final PrivilegedAction<AttributeAccess> action = new PrivilegedAction<AttributeAccess>() { final PrivilegedAction<AttributeAccess> action = () -> {
@Override for ( Class<?> clazz : classHierarchy ) {
public AttributeAccess run() { try {
for ( Class clazz : classHierarchy ) { return new FieldAttributeAccess( clazz.getDeclaredField( attributeName ) );
try { }
final Field field = clazz.getDeclaredField( attributeName ); catch ( NoSuchFieldException e ) {
if ( field != null ) { final Method method = getMethod( clazz, attributeName );
return new FieldAttributeAccess( field ); if ( method != null ) {
} return new MethodAttributeAccess( attributeName, method );
}
catch ( NoSuchFieldException e ) {
final Method method = getMethod( clazz, attributeName );
if ( method != null ) {
return new MethodAttributeAccess( attributeName, method );
}
} }
} }
//we could not find any match
return new NoSuchAttributeAccess( specifiedClass, attributeName );
} }
//we could not find any match
return new NoSuchAttributeAccess( specifiedClass, attributeName );
}; };
return SystemSecurityManager.isSecurityManagerEnabled() ? AccessController.doPrivileged( action ) : action.run(); return SystemSecurityManager.isSecurityManagerEnabled() ? doPrivileged( action ) : action.run();
} }
} }

View File

@ -130,7 +130,7 @@ public class PersistenceUtilHelperTest {
public void testIsLoadedWithNullInterceptor() { public void testIsLoadedWithNullInterceptor() {
assertEquals( assertEquals(
LoadState.LOADED, LoadState.LOADED,
PersistenceUtilHelper.isLoaded( PersistenceUtilHelper.getLoadState(
new PersistentAttributeInterceptable() { new PersistentAttributeInterceptable() {
@Override @Override

View File

@ -28,14 +28,14 @@ public class ProviderUtilTest extends BaseEntityManagerFunctionalTestCase {
public void testIsLoadedOnUnknownClass() { public void testIsLoadedOnUnknownClass() {
final Object entity = new Object(); final Object entity = new Object();
assertTrue( Persistence.getPersistenceUtil().isLoaded( entity ) ); assertTrue( Persistence.getPersistenceUtil().isLoaded( entity ) );
assertEquals( LoadState.UNKNOWN, PersistenceUtilHelper.isLoaded( entity ) ); assertEquals( LoadState.UNKNOWN, PersistenceUtilHelper.getLoadState( entity ) );
} }
@Test @Test
public void testIsLoadedOnKnownClass() { public void testIsLoadedOnKnownClass() {
final Author entity = new Author(); final Author entity = new Author();
assertTrue( Persistence.getPersistenceUtil().isLoaded( entity ) ); assertTrue( Persistence.getPersistenceUtil().isLoaded( entity ) );
assertEquals( LoadState.UNKNOWN, PersistenceUtilHelper.isLoaded( entity ) ); assertEquals( LoadState.UNKNOWN, PersistenceUtilHelper.getLoadState( entity ) );
} }
@Test @Test