Tuesday
Nov022004
Hibernate + DAO Pattern
Tuesday, November 2, 2004 at 4:20PM
After struggling for a few days, performing alot of google searches, and even implementing some code with Spring, I finally got a working DAO setup for our app.
The problem for me was Hibernate's Session. I pilfered code from various Hibernate examples to implement a ThreadLocal Session pattern. Then I wrote a Factory for the DAO. This Factory hides the backend persistence mechanism quite well, enabling the Tapestry components to do simple things like:
The
When a DAO is created, it hits the HibernateUtil class and attempts to begin a new Transaction. There is nothing that commits this transaction automagically, as this could cause unexpected results. It's still up to the code we write in the Tapestry components to call
My only problems now are the aforementioned Transaction mess, and the fact that every call to
Tapestry has now decided we can safely use it's enhancing shit for setters and getters. It suddenly started working the yesterday, but we aren't sure what made it work. I'm sure it was our fault somehow. I just trimmed 1/3rd of the code from a component by getting rid of the implementations of crap like getSomeVar()/setSomeVar() for a bunch of properties and making them abstract methods.
On a side side note, if you use primitives for IDs in Hibernate then
The problem for me was Hibernate's Session. I pilfered code from various Hibernate examples to implement a ThreadLocal Session pattern. Then I wrote a Factory for the DAO. This Factory hides the backend persistence mechanism quite well, enabling the Tapestry components to do simple things like:
CampaignDAO cdao = DAOFactory.getDAOFactory().getCampaignDAO();
Campaign camp = cdao.findCampaignById(id);
camp.setName("New Name");
cdao.saveCampaign(camp);
The
getDAOFactory() method actually returns a HibernateDAOFactory in my code. The same method can be called with an argument to specify a different DAOFactory implementation, but there is only one in my setup currently.When a DAO is created, it hits the HibernateUtil class and attempts to begin a new Transaction. There is nothing that commits this transaction automagically, as this could cause unexpected results. It's still up to the code we write in the Tapestry components to call
HibernateUtil.commitTransaction() to commit the TreadLocal Transaction in the ThreadLocal Session.My only problems now are the aforementioned Transaction mess, and the fact that every call to
DAOFactory.getDAOFactory() instantiates a new HibernateDAOFactory. I'm sure I need to cache or ThreadLocal an instance of some or all of these Objects. Otherwise, I'm putting alot of young objects in and out of the VM for no good reason.Tapestry has now decided we can safely use it's enhancing shit for setters and getters. It suddenly started working the yesterday, but we aren't sure what made it work. I'm sure it was our fault somehow. I just trimmed 1/3rd of the code from a component by getting rid of the implementations of crap like getSomeVar()/setSomeVar() for a bunch of properties and making them abstract methods.
On a side side note, if you use primitives for IDs in Hibernate then
Session.saveOrUpdate() dies with an error message about batch counts. This is, FWICT, because a primitive can't be null, so when you create an empty Campaign, it's id defaults to 0 if it is a long. Changing all my code for 2 pages to use a Long has eliminated that problem.
in
General
General 
Reader Comments (1)
Quote of the day
"An object with 40 fields is why you use an ORM." - Cory
Funny thing is, after our experiences with Hibernate I had been wondering why the hell anyone wants to use an ORM.