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).