Transaction management difficulty in Composite Entity Design
According to J2EE Design pattern book, I抦 trying to design better 揅omposite?Entity Bean. The book says, 揈ntity beans are not intended to represent every persistent object in the object model. Entity beans are better suited for coarse-grained persistent business objects?(310 Core J2EE Patterns). They call it 揅omposite Entity.? Here is little explanation about composite entity.
http://www.ciol.com/content/technology/j2ee/
Sounds interesting and the book convinces me. However, as I designed my 揷omposite?entity beans, I encountered some difficulty. The example source codes in the book use a couple of model objects called 揤alue Object?and DAOs. It means that one entity bean doesn抰 simply represent one row data in one table. It represents 揷omposite?data from many tables as name indicates.
And here is my question: how can we manage transactions in composite entity? In entity bean specification, only CMP entity beans support transactions (managed by container). However, composite entity obviously doesn't fit in CMP, so a natural choice would be BMP. But we cannot use JDBC transaction or JTA transaction in BMP entity beans, right? (Actually, I failed.) If we use a session bean and it directly accesses database through DAO, it wouldn抰 violate EJB specification since session beans support transactions (Sun抯 pet store below, for example).
http://java.sun.com/j2ee/sdk_1.2.1/techdocs/guides/ejb/examples/warehouse/WarehouseEJB.java
But this is not the case here. I need a entity bean to support synchronization and concurrent accesses to data.
The followings are example codes from 揅ore J2EE Patterns?book (325). As you can see, if second or third DAO抯 deleting operation were failed, we would lose data consistency. This ejbRemove operation must remove all data from three tables or rollback operations and throw an exception.
publicclass ResourceEntityimplements EntityBean{
...
publicvoid ejbRemove(){
try{
//Remove dependent objects
if (this.skillSets !=null){
SkillSetDAO skillSetDAO = getSkillSetDAO();
skillSetDAO.setResourceID(employeeId);
skillSetDAO.deleteAll();
skillSets =null;
}
if (this.blockoutTime !=null){
BlockOutTimeDAO = blockouttimeDAO = getBlockOutTimeDAO();
blockouttimeDAO.setResourceID(employeeId);
blockouttimeDAO.deleteAll();
blockOutTimes =null;
}
//Remove the resource from the persistent store
ResourceDAO resourceDAO =new ResourceDAO(employeeId);
resourceDAO.delete();
}catch (ResourceException ex){
...
}
}
...
}
What is a better design in this case? I really appreciate any opinions and arguments.
Thanks.
-tom

