Tuesday, June 29, 2010

Mapping issue with nullable primitive types in hibernate.

Problem description :
You have many columns in a table which are mapped as primitives in Hibernate and you have the getters and setters ready .But the code is giving "PropertyAccessException" .It is quite a common exception for hibernate users .There is a post regarding this in the Hibernate Official Web site in common problem section , which is like the following :

Hibernate throws a PropertyAccessException or NullPointerException
when I load or query an object!
A PropertyAccessException often occurs when the object being passed to the setter method is of the wrong type. Check your type mappings for the offending property. (To see exactly which property was the problem, you might need to disable the CGLIB reflection optimizer.) However, the most common cause of this problem is that Hibernate attempted to assign null to a property of primitive type.
If your object has a primitive-type property mapped to a nullable database column then you will need to use a Hibernate custom type to assign a sensible default (primitive) value for the case of a
null column value. A better solution is usually to use a wrapper type for the Java property.

Analysis and solution:
Fair enough...,providing an Integer mapping instead of int (i.e. using wrapper class of Java) is off course a better solution (as well as common practice ) when the design is in your hand .
But
what if the POJOs are already written and you can not modify them? (Oh my God !!!)

Well, in that case my solution is using Hibernates formula attribute .It will be like the following:

property name="primitiveNullableDemoField" formula=”COALESCE(primitiveNullableDemoField, 0)


So the core idea is to replace the null field with default (not null ) initialization value.

Disclaimer:
Now there are two issues
1. COALESCE () function is DB2 specific solution; it will not work in Oracle.
2. Adding a function in the query adds to database overhead .I have heard about situations where DBAs do not allow to the developers to fire any DB functions considering the performance issue in critical scenarios (Too much, isn’t it?).
Regarding point 1, I do not know a common or generic function to replace null value that works for all Databases. Instead we can use case statements to bypass this.

No comments:

Post a Comment