If you worked with the DAO and the Persistence Manager concepts, you must have noticed the mutual incompatibility between the two. While a DAO provides an interface for persisting your objects at your request, the Persistence Manager takes on a more active role, that of maintaining your object state in the persistence store, when working with objects originating or in the persistence store. All is nice until you try to marry the two or to promise easy switching between one and the other. The most common flavor of this promise is that you make a DAO layer as insulating layer and then you can base its implementation on either plain JDBC or on a persistence framework.
Problem 1
Take the following use case:
- Begin transaction
- Create object
- Save object to persistence store
- Change object in memory
- Commit transaction without saving
When working with DAOs, you expect the in-memory changes to be lost at the end of the use case. By contrast, when using the persistence manager, you expect these changes to be automatically persisted, due to the object being a persistent object by the end of third step. You can’t implement this use case in a fully agnostic manner, because it just does not retain semantics across these two approaches to persistence.
So I asked Spring Framework how they solve this problem. Spring is intended to be the holy grail of J2EE development, and is widely embraced today. As such, it supports approaching persistence with DAOs on top of plain JDBC, or full-blown persistence layer, like Hibernate, Toplink, or EJB 3. So I checked their Pet Clinic application, and guess what: they don’t solve the problem either. The DAO layer will rest on JDBC, or Hibernate, depending on the direction you want to go, but your use case may have different semantics when used with a persistence manager.
Solution: choose one approach and stick with it. Embrace the persistence manager approach and do away with DAOs, after all, the persistence manager already provides high level means of both reading and writing your data to the store. High level query language such as Hibernate’s criteria are powerful and clean. Embrace the DAO approach and enforce certain semantics, even if your DAO layer builds on a persistence framework. The most important, making sure that the objects returned are not persistent, and therefore use cases like the above are not affected.
Problem 2
Consider this use case:
- Begin transaction
- Load an object from your persistence store
- Load another object from your persistence store, using the same query
- Test whether the two objects are the same
- End transaction
Object identity is another promise of your persistence framework, one not embraced by typical DAO implementations. So when trying to marry the two, the above use case will have an unexpected outcome. Your persistence layer guarantees object identity for objects created by the same session. DAOs do not. When implementing the promise of your DAO layer, you must specify the expected semantics of your DAO classes with respect to object identity and make sure to implement it properly.
Solution: choose whether to enforce object identity within the same transaction or not. In the former case, you’ll have a lot of trouble figuring out transaction boundaries when implemented a JDBC-based DAO layer, whereas in the latter case, you’ll have to do some fiddling when basing your DAO layer on a persistence framework.
Post a Comment
You must be logged in to post a comment.