Wrong class property type, when access="field" is specified. The HbmBinder and
the method setTypeUsingReflection() of the interface org.hibernate.mapping.Value does not
use the property "access" settings (field/property/etc...)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key: HHH-4770
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-4770
Project: Hibernate Core
Issue Type: Bug
Components: core, metamodel
Affects Versions: 3.5.0-Beta-2, 3.3.2
Reporter: Peter Fassev
Attachments: ReflectionTest.zip
Hibernate provides a possibility to define different access to the class properties for
instance trough class methods (access="property") or directly to fields
(access="field"). This information is not used during the initialization of the
subclasses of the org.hibernate.mapping.Value (see SimpleValue and ToOne).
The Value interface provides a method called setTypeUsingReflection(String className,
String propertyName) with only two parameters. Some subclasses like SimpleValue and ToOne
are calling the ReflectHelper.reflectedPropertyClass(className, propertyName). The
ReflectHelper uses first the BASIC_PROPERTY_ACCESSOR, which always returns the type of the
class method. Only if there is no such method, the type of the class field is returned. It
does not distinguish between "property" and "field" access. Here is
the Method from the ReflectHelper:
org.hibernate.util.ReflectHelper:
private static Getter getter(Class clazz, String name) throws MappingException {
try {
return BASIC_PROPERTY_ACCESSOR.getGetter( clazz, name );
}
catch ( PropertyNotFoundException pnfe ) {
return DIRECT_PROPERTY_ACCESSOR.getGetter( clazz, name );
}
}
In the case the declared method returns a different type as the declared field Hibernate
calculates a wrong type for the fild. Consider the following class with a hidden field
"rejected" of type "Date" and a method "isRecected()" of
type boolean:
class Item {
private Date rejected;
public void doReject() {
rejected = new Date();
}
public boolean isRejected() {
return rejected != null;
}
}
This type of the rejected field will be recognized by Hibernate as "boolean",
even if the field access is defined to be "access=field". By running the
ReflectionTestCase you will get an exception: "java.util.Date cannot be cast to
java.lang.Boolean".
Proposed Resolution:
1) The method org.hibernate.mapping.Value. setTypeUsingReflection needs a new parameter,
which provides the access type of the property.
2) The class org.hibernate.mapping.HbmBinder must bind the access attribute of the
property prior of calling this method, which is currently not the case (see the method
HbmBinder.createProperty()).
3) The classess SimpleValue and ToOne should either use the PropertyAccessorFactory or the
ReflectHelper should be extended to handle the access type of the field.
Regards
PF
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira