Generic EJB 3 CRUD, DTOs and Lost Updates with Optimistic Locks and JPA
I got some feedback with concerns about a generic CRUD interface which I described in this post, as well as checked in into p4j5. The basic idea was the direct exposure of persistent JPA-entities to a remote client - without the use of DTOs. This approach works really well for simple use cases like e.g. master data management. However it isn't a silver bullet for more complex use cases. In general, the @Version in an JPA-entity is going to change in case the persistent state (the attributes) is changed. However the relations do not belong to this set. So, even in case you are using JPA with optimistic concurrency, changes to relations do not cause the @Version attribute to be increased / changed. In case the client changes a relation (e.g. deletes a link between the master 1----n> client), the @Version of the master entity will not be increased - concurrent access could cause lost updates in this case.
Beyond this "logical" problem - before you would like to start using detached entities over network boundaries, you should think about the following challenges:
- Lazy loading - you have to preload the object graph, which is needed at the client. You could use e.g. "FETCH JOINS" for this purpose, or just invoking the methods
- Lazy loading and AOP - some providers weave proprietary extension into the persistent entities. In this case it could be necessary to deploy additional libraries to the client as well.
- The client will need at least the JPA-annotations in the classpath
- In case you are sending a subset of the object graph to the client - automatic merge will be not always possible (what happens, in case the client deletes some childs?)
I will discuss this issue in more detail during the upcoming talk at JUG HH (19.05.2008) as well.
If using Hibernate as the JPA provider, the BeanLib project can un-weave the entities to solve points 2 and 3.
Posted by Greg Burrow on May 20, 2008 at 12:11 AM CEST #