]
Ondrej Medek commented on HHH-3718:
-----------------------------------
Although I would like Hibernate would behave the same way with access type either field or
property, I have to agree with Christian. This path is a nice try, but makes thinks more
obfuscated when the patch does not find the proper @Id getter method.
Maybe a "clean" solution would be to have an annotation like
@Id(property="myID") which could tell Hibernate which property to look for when
it has some uncommon name. Maybe such "property" property could be for every
field @Basic(property="...") and then Hibernate could behave always like for
AccessType("property").
Furthermore, this patch does not create the getter name in a proper way. E.g. a Java
convention for a field like "cId" is to make getter "getcId" (yes,
lower case "c"). That is, does not capitalize the first letter when the second
letter is a capital.
call to id getter initializes proxy when using AccessType(
"field" )
--------------------------------------------------------------------
Key: HHH-3718
URL:
https://hibernate.onjira.com/browse/HHH-3718
Project: Hibernate ORM
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
Assignee: Strong Liu
Fix For: 4.1.x
Attachments: ids.patch, 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.
For more information on JIRA, see: