jhoeller wrote:
Don't start with HibernateDaoSupport but rather with the "big picture" :-)
The very points of Spring's transaction and DAO support are to decouple transaction demarcation from DAOs (moving it to business facades), to allow for generic DAO interfaces (with generic DataAccessExceptions), and to allow for DAO implementations that can easily participate in any transaction strategy.
...
DAO implementations do not have to care about resource or transaction management but rather focus on the actual data access operations. Using Spring's HibernateTemplate, for example with the convenience base class HibernateDaoSupport, can result in one-liners for typical data access operations (see the Petclinic sample).
I can't agree more. I recently converted an application to a spring managed middle tier. Previously the application consisted basically of struts actions calling dao methods, with transaction management in the dao:s. By introducing a service layer with spring managed declarative transactions, I was able to move to a "single database transaction per http request" model, compared to the previous version where a single http request could typically result in dozens of transactions. This is of course an important safety feature in case of writes, as the database is always in a consistent state from the viewpoint of the application when using the "single database transaction per http request" model. Although I haven't measured, there should also be improved performance as there is less need for database roundtrips because the applications isn't committing all the time.
The funny thing about spring is that it feels as if it doesn't get in the way (thanks to AOP and IOC I guess), while at the same time "nudging" you towards a "best practices" architecture. I guess it's a combination of good design, good documentation and good examples. Boing Boing! ;-)
Quote:
I hope that makes Spring's transaction and persistence support a bit clearer. Note that Matt Raible's AppFuse (mentioned by Anthony in an earlier post) is now built on a Spring-managed middle tier as of version 1.4, offering Spring's Hibernate and iBATIS SQL Maps support as data access strategies.
While I haven't used appfuse to bootstrap my own projects, I have drawn a lot of inspiration from it. It very good code, IMHO, except for a few small grievances:
- He still seems to have his old checked DAOException class around, so lots of methods have to declare throws. The Hibernate DAO classes use DataAccessException from spring, but what does that help when the DAO interfaces still use DAOException? Anyway, this is quickly remedied.
- He has hashCode and equals() in his BaseObject (his base persistent class), made using the commons reflection builders. I prefer to specify these methods separately for every persistent class, specifying some static fields manually instead of using the reflection builders, because the reflection builders will obviously also use fields that will change during the lifetime of the object (there is an informative page on the hibernate wiki about making good equals and hashCode methods). Again, this is not a big problem to fix if one decides to use appfuse. But it is something to be aware of, as failing to do so can lead to subtle bugs appearing.