Last week we tried to switch from Hibernate 2 to Hibernate 3. After reading the migration guide it didn't seem that much of a problem.
Seems we were wrong in that assumption. We've run into lots of problems (and we are not finished yet...), and I'm sure we'd have stayed with Hibernate 2 if we knew beforehand.
Anyway, here is a list of the some of the problems we encountered. Maybe some of that should be put into the migration guide. Ather points may be just misunderstanding on our side. I'd be grateful for any information about this.
Some information about the application scenario: Our application has about 40 persistent classes. We define each class using a .hbm.xml file and let Hibernate create the Java files and the SQL DDL.
Most, but not all problems are related to the hbm2java code generation tool.
1. Hibernate 3 no longer creates hashCode() and equals() methods.
In Hibernate 2 you could use the meta tag "implement-equals" to create equals() and hashcode(). Additional infomation in the property definition specified which properties were to be used in these methods.
Hibernate 3 apparently no longer supports the "implement-equals" meta tag. equals() and hashCode() must be implemented manually.
2. In Hibernate 2 the Java code generated by Hibernate implemented boolean attributes that were not nullable as boolean (the primitive type). Hibernate 3 creates these attributes as Boolean objects. An additional complication is the fact that the Boolean attributes are initialized with null. As a result of this change all objects initialization must be changed to set these attributes (where in the past the default value of false might have been sufficient), and all calls to the getter/setter methods must be changed to deal with Boolean objects instead of boolean values.
3. As a related point: The getter methods to boolean attributes used to be named isAttribute(), now the hbm2java tools creates getAttribute() instead (where "Attribute" is the attribute name).
4. The Hibernate 2 hbm2java tool used to create four constructors for each class: one default constructor, one with only the ID as parameter, one taking all not nullable attributes, and one with all attributes. The code generated by hibernate 3 only creates the default constructor and the one taking the ID. All calls using one of the other constructors must be changed.
5. In Hibernate 2 you had the *option* to use a proxy class for lazy loading of many-to-one and one-to-one associations. This was well documented, as was the fact that this appoach was highly problematic if you were using polymorphic classes (unless you defined interfaces for all your persistent classes). Hibernate 3 uses this problematic approach now by default, even for direct loading. Now, if I ask hibernate to load a specific inctance of one class (by specifying its ID) hibernate will create a proxy, which can *not* be casted to the respective subclass represented by the object. This means if the are using polymorphic classes you must create interfaces (manually) for all classes, you must use these interfaces in all references to the objects, and you must modify the hbm.xml files to use these interfaces as proxies. All that, even if you don't use lazy loading of many-to-one or one-to-one associations.
That's all I can think of the top of my head right now. I'll add to this if we find more problems.
|