HHH-10511 - drop EnhancedGetterMethod: use GetterMethod / GetterField instead
This commit is contained in:
parent
a24eecf7da
commit
5c567bb4bf
|
@ -12,10 +12,10 @@ import java.lang.reflect.Method;
|
||||||
import org.hibernate.PropertyNotFoundException;
|
import org.hibernate.PropertyNotFoundException;
|
||||||
import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
|
import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.property.access.spi.EnhancedGetterMethodImpl;
|
import org.hibernate.property.access.spi.EnhancedSetterImpl;
|
||||||
import org.hibernate.property.access.spi.EnhancedSetterMethodImpl;
|
|
||||||
import org.hibernate.property.access.spi.Getter;
|
import org.hibernate.property.access.spi.Getter;
|
||||||
import org.hibernate.property.access.spi.GetterFieldImpl;
|
import org.hibernate.property.access.spi.GetterFieldImpl;
|
||||||
|
import org.hibernate.property.access.spi.GetterMethodImpl;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
import org.hibernate.property.access.spi.PropertyAccessBuildingException;
|
import org.hibernate.property.access.spi.PropertyAccessBuildingException;
|
||||||
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||||
|
@ -23,9 +23,8 @@ import org.hibernate.property.access.spi.Setter;
|
||||||
import org.hibernate.property.access.spi.SetterFieldImpl;
|
import org.hibernate.property.access.spi.SetterFieldImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A PropertyAccess for byte code enhanced entities. Enhanced getter / setter methods ( if available ) are used for
|
* A PropertyAccess for byte code enhanced entities. Enhanced setter methods ( if available ) are used for
|
||||||
* field access. Regular getter / setter methods are used for property access. In both cases, delegates calls to
|
* property writes. Regular getter methods/fields are used for property access. Based upon PropertyAccessMixedImpl.
|
||||||
* EnhancedMethodGetterImpl / EnhancedMethodGetterImpl. Based upon PropertyAccessMixedImpl.
|
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Luis Barreiro
|
* @author Luis Barreiro
|
||||||
|
@ -45,39 +44,24 @@ public class PropertyAccessEnhancedImpl implements PropertyAccess {
|
||||||
final Field field = fieldOrNull( containerJavaType, propertyName );
|
final Field field = fieldOrNull( containerJavaType, propertyName );
|
||||||
final Method getterMethod = getterMethodOrNull( containerJavaType, propertyName );
|
final Method getterMethod = getterMethodOrNull( containerJavaType, propertyName );
|
||||||
|
|
||||||
final Class propertyJavaType;
|
|
||||||
|
|
||||||
// need one of field or getterMethod to be non-null
|
// need one of field or getterMethod to be non-null
|
||||||
if ( field == null && getterMethod == null ) {
|
if ( field == null && getterMethod == null ) {
|
||||||
String msg = String.format( "Could not locate field nor getter method for property named [%s#%s]",
|
throw new PropertyAccessBuildingException(
|
||||||
containerJavaType.getName(),
|
String.format(
|
||||||
propertyName );
|
"Could not locate field for property [%s] on bytecode-enhanced Class [%s]",
|
||||||
throw new PropertyAccessBuildingException( msg );
|
propertyName,
|
||||||
|
containerJavaType.getName()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if ( field != null ) {
|
else if ( field != null ) {
|
||||||
propertyJavaType = field.getType();
|
this.getter = new GetterFieldImpl( containerJavaType, propertyName, field );
|
||||||
this.getter = resolveGetterForField( containerJavaType, propertyName, field );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
propertyJavaType = getterMethod.getReturnType();
|
this.getter = new GetterMethodImpl( containerJavaType, propertyName, getterMethod );
|
||||||
this.getter = new EnhancedGetterMethodImpl( containerJavaType, propertyName, getterMethod );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Method setterMethod = setterMethodOrNull( containerJavaType, propertyName, propertyJavaType );
|
this.setter = resolveEnhancedSetterForField( containerJavaType, propertyName, field );
|
||||||
|
|
||||||
// need one of field or setterMethod to be non-null
|
|
||||||
if ( field == null && setterMethod == null ) {
|
|
||||||
String msg = String.format( "Could not locate field nor getter method for property named [%s#%s]",
|
|
||||||
containerJavaType.getName(),
|
|
||||||
propertyName );
|
|
||||||
throw new PropertyAccessBuildingException( msg );
|
|
||||||
}
|
|
||||||
else if ( field != null ) {
|
|
||||||
this.setter = resolveSetterForField( containerJavaType, propertyName, field );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.setter = new EnhancedSetterMethodImpl( containerJavaType, propertyName, setterMethod );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Field fieldOrNull(Class containerJavaType, String propertyName) {
|
private static Field fieldOrNull(Class containerJavaType, String propertyName) {
|
||||||
|
@ -98,36 +82,12 @@ public class PropertyAccessEnhancedImpl implements PropertyAccess {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Method setterMethodOrNull(Class containerJavaType, String propertyName, Class propertyJavaType) {
|
private static Setter resolveEnhancedSetterForField(Class<?> containerClass, String propertyName, Field field) {
|
||||||
try {
|
|
||||||
return ReflectHelper.findSetterMethod( containerJavaType, propertyName, propertyJavaType );
|
|
||||||
}
|
|
||||||
catch (PropertyNotFoundException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
private static Getter resolveGetterForField(Class<?> containerClass, String propertyName, Field field) {
|
|
||||||
try {
|
|
||||||
String enhancedGetterName = EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + propertyName;
|
|
||||||
Method enhancedGetter = containerClass.getDeclaredMethod( enhancedGetterName );
|
|
||||||
enhancedGetter.setAccessible( true );
|
|
||||||
return new EnhancedGetterMethodImpl( containerClass, propertyName, enhancedGetter );
|
|
||||||
}
|
|
||||||
catch (NoSuchMethodException e) {
|
|
||||||
// enhancedGetter = null --- field not enhanced: fallback to reflection using the field
|
|
||||||
return new GetterFieldImpl( containerClass, propertyName, field );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Setter resolveSetterForField(Class<?> containerClass, String propertyName, Field field) {
|
|
||||||
try {
|
try {
|
||||||
String enhancedSetterName = EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + propertyName;
|
String enhancedSetterName = EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + propertyName;
|
||||||
Method enhancedSetter = containerClass.getDeclaredMethod( enhancedSetterName, field.getType() );
|
Method enhancedSetter = containerClass.getDeclaredMethod( enhancedSetterName, field.getType() );
|
||||||
enhancedSetter.setAccessible( true );
|
enhancedSetter.setAccessible( true );
|
||||||
return new EnhancedSetterMethodImpl( containerClass, propertyName, enhancedSetter );
|
return new EnhancedSetterImpl( containerClass, propertyName, enhancedSetter );
|
||||||
}
|
}
|
||||||
catch (NoSuchMethodException e) {
|
catch (NoSuchMethodException e) {
|
||||||
// enhancedSetter = null --- field not enhanced: fallback to reflection using the field
|
// enhancedSetter = null --- field not enhanced: fallback to reflection using the field
|
||||||
|
|
|
@ -1,155 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.property.access.spi;
|
|
||||||
|
|
||||||
import java.io.ObjectStreamException;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Member;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.PropertyAccessException;
|
|
||||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoader;
|
|
||||||
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
|
||||||
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
|
|
||||||
import static org.hibernate.internal.CoreLogging.messageLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class EnhancedGetterMethodImpl implements Getter {
|
|
||||||
|
|
||||||
private static final Object[] EMPTY = new Object[0];
|
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = messageLogger( EnhancedGetterMethodImpl.class );
|
|
||||||
|
|
||||||
private final Class containerClass;
|
|
||||||
private final String propertyName;
|
|
||||||
private final Method getterMethod;
|
|
||||||
|
|
||||||
public EnhancedGetterMethodImpl(Class containerClass, String propertyName, Method getterMethod) {
|
|
||||||
this.containerClass = containerClass;
|
|
||||||
this.propertyName = propertyName;
|
|
||||||
this.getterMethod = getterMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isAttributeLoaded(Object owner) {
|
|
||||||
if ( owner instanceof PersistentAttributeInterceptable ) {
|
|
||||||
PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) owner ).$$_hibernate_getInterceptor();
|
|
||||||
if ( interceptor != null && interceptor instanceof LazyAttributeLoader ) {
|
|
||||||
return ( (LazyAttributeLoader) interceptor ).isAttributeLoaded( propertyName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(Object owner) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
// We don't want to trigger lazy loading of byte code enhanced attributes
|
|
||||||
if ( isAttributeLoaded( owner ) ) {
|
|
||||||
return getterMethod.invoke( owner, EMPTY );
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (InvocationTargetException ite) {
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
ite,
|
|
||||||
"Exception occurred inside",
|
|
||||||
false,
|
|
||||||
containerClass,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException iae) {
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
iae,
|
|
||||||
"IllegalAccessException occurred while calling",
|
|
||||||
false,
|
|
||||||
containerClass,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
//cannot occur
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException iae) {
|
|
||||||
LOG.illegalPropertyGetterArgument( containerClass.getName(), propertyName );
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
iae,
|
|
||||||
"IllegalArgumentException occurred calling",
|
|
||||||
false,
|
|
||||||
containerClass,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getForInsert(Object owner, Map mergeMap, SessionImplementor session) {
|
|
||||||
return get( owner );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class getReturnType() {
|
|
||||||
return getterMethod.getReturnType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Member getMember() {
|
|
||||||
return getterMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return getterMethod.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return getterMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object writeReplace() throws ObjectStreamException {
|
|
||||||
return new SerialForm( containerClass, propertyName, getterMethod );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SerialForm implements Serializable {
|
|
||||||
private final Class containerClass;
|
|
||||||
private final String propertyName;
|
|
||||||
|
|
||||||
private final Class declaringClass;
|
|
||||||
private final String methodName;
|
|
||||||
|
|
||||||
private SerialForm(Class containerClass, String propertyName, Method method) {
|
|
||||||
this.containerClass = containerClass;
|
|
||||||
this.propertyName = propertyName;
|
|
||||||
this.declaringClass = method.getDeclaringClass();
|
|
||||||
this.methodName = method.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object readResolve() {
|
|
||||||
return new EnhancedGetterMethodImpl( containerClass, propertyName, resolveMethod() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private Method resolveMethod() {
|
|
||||||
try {
|
|
||||||
return declaringClass.getDeclaredMethod( methodName );
|
|
||||||
}
|
|
||||||
catch (NoSuchMethodException e) {
|
|
||||||
throw new PropertyAccessSerializationException(
|
|
||||||
"Unable to resolve getter method on deserialization : " + declaringClass.getName() + "#" + methodName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,8 +22,8 @@ import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class EnhancedSetterMethodImpl implements Setter {
|
public class EnhancedSetterImpl implements Setter {
|
||||||
private static final CoreMessageLogger LOG = messageLogger( EnhancedSetterMethodImpl.class );
|
private static final CoreMessageLogger LOG = messageLogger( EnhancedSetterImpl.class );
|
||||||
|
|
||||||
private final Class containerClass;
|
private final Class containerClass;
|
||||||
private final String propertyName;
|
private final String propertyName;
|
||||||
|
@ -31,7 +31,7 @@ public class EnhancedSetterMethodImpl implements Setter {
|
||||||
|
|
||||||
private final boolean isPrimitive;
|
private final boolean isPrimitive;
|
||||||
|
|
||||||
public EnhancedSetterMethodImpl(Class containerClass, String propertyName, Method setterMethod) {
|
public EnhancedSetterImpl(Class containerClass, String propertyName, Method setterMethod) {
|
||||||
this.containerClass = containerClass;
|
this.containerClass = containerClass;
|
||||||
this.propertyName = propertyName;
|
this.propertyName = propertyName;
|
||||||
this.setterMethod = setterMethod;
|
this.setterMethod = setterMethod;
|
||||||
|
@ -153,7 +153,7 @@ public class EnhancedSetterMethodImpl implements Setter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object readResolve() {
|
private Object readResolve() {
|
||||||
return new EnhancedSetterMethodImpl( containerClass, propertyName, resolveMethod() );
|
return new EnhancedSetterImpl( containerClass, propertyName, resolveMethod() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
Loading…
Reference in New Issue