]
Paul Lorenz commented on HHH-3718:
----------------------------------
I've added a patch to solve this problem slightly different, using a lazy lookup of
the method.
We're also having a problem where the method being invoked is different from
identified get method.
We have a common interface for entities which includes a method
Serializable getId ()
in a subclass, we have
Long getId ()
When the proxy is invoked, it invokes the Serializable getId () method, however the
getIdentifierMethod in BasicLazyInitializer is the Long getId() method. Since they
don't match, it initializes the proxy.
I replaced this with a heuristic based on method name and number of arguments, since this
should be more accurate.
call to id getter initializes proxy when using AccessType(
"field" )
--------------------------------------------------------------------
Key: HHH-3718
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3718
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.3.1
Environment: hibernate 3.3.1, hibernate annotations 3.4.0, running on windows,
linux and solaris, using sybase 15
Reporter: Paul Lorenz
Attachments: ids.patch
Calling getter for id when using AccessType( "field" ) causes proxy
initialization.
In org.hibernate.proxy.proxy.pojo.BasicLazyInitializer there is the code
else if ( isUninitialized() && method.equals(getIdentifierMethod) ) {
return getIdentifier();
}
However, when using field access, the getIdentifierMethod will be null. I fixed this for
us by changing DirectPropertyAccessor by adding a Method attribute to the DirectGetter
inner class, and looking up the appropriate getter in the constructor. As far as I can
tell, getMethod is only used in two places. In the above case, to the get the identity
getter and in PojoComponentTupilizer.isMethodOf. This doesn't seem to break anything.
I don't know if this is a clean solution, seems a little hacky to me, however, it
would be great if the issue could be fixed somehow.
public static final class DirectGetter implements Getter {
private final transient Field field;
private final Class clazz;
private final String name;
private Method method;
DirectGetter(Field field, Class clazz, String name) {
this.field = field;
this.clazz = clazz;
this.name = name;
try
{
BeanInfo beanInfo = Introspector.getBeanInfo( clazz );
PropertyDescriptor[] pdArray = beanInfo.getPropertyDescriptors();
if ( pdArray != null )
{
for (PropertyDescriptor pd : pdArray )
{
if ( pd.getName().equals( name ) )
{
this.method = pd.getReadMethod();
}
}
}
}
catch ( Exception e )
{
// ignore
}
}
public Object get(Object target) throws HibernateException {
try {
return field.get(target);
}
catch (Exception e) {
throw new PropertyAccessException(e, "could not get a field value by
reflection", false, clazz, name);
}
}
public Object getForInsert(Object target, Map mergeMap, SessionImplementor session)
{
return get( target );
}
public Method getMethod() {
return method;
}
public String getMethodName() {
return method == null ? null : method.getName();
}
public Class getReturnType() {
return field.getType();
}
Object readResolve() {
return new DirectGetter( getField(clazz, name), clazz, name );
}
public String toString() {
return "DirectGetter(" + clazz.getName() + '.' + name +
')';
}
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: