Hibernate Upgade: 1.2.3 to 2.0 (My Story)
I'm upgrading struts-resume to Hibernate 2.0 tonight. I thought I'd blog my adventure and what I needed to change.
.hbm.xml files.
Step 2: Download Hibernate 2.0 beta 2. It's at the bottom of the preceding link.
Step 3: Extract to struts-resume/lib and change
lib.properties to version 2.0.Step 4: Edit
build.xml file to pick up the new DTD. I changed <hibernate/> to be <hibernate validatexml="true" version="2.0"/>.Step 5: Using HomeSite, I did
s/cirrus.hibernate/net.sf.hibernate/g. 14 matches. The project currently has 3 DAO's and a ServiceLocator to get Hibernate Sessions.Step 6:
ant clean deploy Not too bad, only one compile error.
D:\source\appfuse\src\ejb\org\appfuse\persistence\ServiceLocator.java:12: cannot resolve symbol
symbol : class Datastore
location: package hibernate
import net.sf.hibernate.Datastore;
Step 7: Open up Eclipse, refresh the project and right click on the project name, click Properties >> Java Build Path. Change path for
hibernate.jar to struts-resume/lib/hibernate-2.0/hibernate.jar. Remove the previous path.Step 8: Go searching for what the heck happened to Datastore. Hibernate CVS is first choice. Pause to post (per chance someone reads and sends solution).
Step 9: Step 4 from the Hibernate 2 Porting Guidelines. Replacing attribute names, DTDs and changed
throws SQLException to JDBCException in ServiceLocator class.Step 10: Repeat Step 5 for all Unit tests (they live in "test," rather than "src"). End up repeating for entire project, makes about 1800 replacements - hibernate-1.2.3/src was in search path. Remove lib/hibernate-1.2.3.
Step 11: Revisit Step 8 and try to use new Configuration API. Tried this...
Datastore datastore = Hibernate.createDatastore() - changed to Configuration config = new Configuration();
Not working yet... But Gavin has responded to the mailing list and Chiara is listening. Good to have the support ;-)
Step 12: Found a problem with XDoclet, modifying source. Changing "role" attribute to "name" for the following types (in order replaced by HomeSite): subcollection, collection, set, bag, list, map, array, primitive-array. Rebuilt hibernate module. Changed attribute "readonly" to "inverse" and tried again. Changes to set and bag only.
Step 13: I'm using the
Configure.configure() method to initialize from hibernate.cfg.xml (I had to rename the package for my dialect from cirrus.hibernate.sql.MySQLDialect to net.sf.hibernate.dialect.MySQLDialect). I doubt it'll work though since this expects a JNDI DataSource.Step 14: Nope, that didn't work. I found out I needed to remove the "length" attribute from any <key> elements in <bag>'s. Back to trying to use
config.addClass().Step 15: Internet connection goes down, reboot router. Change dialect package name in
database.properties. This file is renamed to hibernate.properties and used for running JUnit tests. Now time to have fun with JUnit and get UserDAOTest to run.
I'm getting a connection to the database now thanks to Gavin's advice:
sf = new Configuration()
.addClass(Foo.class)
.addClass(Bar.class)
.buildSessionFactory();
Step 16: Changed xdoclet tags "inverse" attribute to be "false" where previously
readonly="true", now inverse="false". Now I'm getting the following error:
[junit] java.sql.BatchUpdateException: Invalid argument value: Duplicate entry '0' for key 1
[junit] at com.mysql.jdbc.jdbc2.PreparedStatement.executeBatch(Unknown Source)
Whenever I try to run the
addResume test for a user. The mapping looks fine, I'll try dropping and re-creating the database. Found I needed to change the package names in build.xml. Note to upgraders: don't filter by file extension when replacing the package name.
Discovered that the
SchemaExport class had moved from net.sf.hibernate.tools to net.sf.hibernate.tool.hbm2ddl.
Step 17: The
UserDAOTest runs successfully. Now for the web...
Couldn't get "
ant test-canoo" (Canoo WebTest) to run until I copied xerces.jar back into lib/hibernate-2.0/lib. Changed my log4j.properties to use new package name for logging.
After looking at some 2.0 documentation, I discovered a new DTD for hibernate-configuration. Unfortunately, it's not there. So I put it on this site as a workaround. Got rid of startup errors. One change in the DTDs is that all <property> declarations must be within a <session-factory> element.
Now I can't get Hibernate to connect to JNDI. Back to the doco...
(5 minutes later) Yep, right in the doco. I changed
StartupServlet.java to have the following:
SessionFactory sf =
new Configuration().configure().buildSessionFactory();
Now, when I login I'm getting:
java.lang.UnsupportedOperationException
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:125)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:329)
Since my Unit tests on the business level run, I'm guessing it's something wrong with this line in hibernate.cfg.xml:
<property name="connection.datasource">java:comp/env/jdbc/resume</property>
Get a good nights sleep; zonked out at 3, up at 8:30 to continue...
Step 18: Find out (from Gavin) that there's probably a
hibernate.properties file in my classpath that is causing the problem. I find this fine inside hibernate.jar. Doh! There's an error in packaging. ;-) I remembering seeing this sometime last week on the mailing list. I decide to upgrade to Hibernate 2.0 beta 3, which was released while I was sleeping. The file hibernate.properties is removed from hibernate2.jar in this release. I did have to update lib/lib.properties to handle the change of jar-name. Compiling, testing...
Dropped and re-created the database b/c I was getting duplicate key errors. Ran
UserDAOTest - BUILD SUCCESSFUL - run it again - BUILD FAILED.
Further updates to
hibernate-properties.xdt to replace paramName="role" to paramName="name", also replaced paramName="readonly" with paramName="inverse". Sent an e-mail to xdoclet-devel inquiring about best way to make hibernate-properties.xdt both 2.0 and 1.1-compatible.
This change in XDoclet makes
UserDAOTest pass - so it looks like the upgrade is a success. Now I just have to figure out a way to convince the XDoclet team to add support for Hibernate 2.0. This might take awhile, it has for POJO -> StrutsForms support (still pending).

