We make use of a very strong domain layer. By strong I mean we it incorporates both data, persisted via Hibernate, and behavior (or business logic).
We use the DAO pattern and abstract factory strategy to determine what DAO implementation we are using at runtime.
Until recently the Domain objects new nothing of the DAOs. The reason for this is that this is taken care of in our service layer (currently implemented via Stateless Session Beans).
Until recently, a typical SSB transaction involving both DAO and domain classes might look like this:
Code:
public CaseDTO getCase(String id)
throws SpotLightException {
CaseDTO dto = null;
prepareSession();
try {
dto = CaseAssembler.writeDTO(SpotLightDAOFactory.getDAOFactory()
.getCaseDAO().findCaseById(id);
}
catch (Exception e) {
getSessionContext().setRollbackOnly();
throw (SpotLightException) SpotLightExceptionConverter.convert(e);
}
finally {
closeSession();
}
return dto;
}
Notice how the Case is loaded via the DAO in the SSB method. This works very well. However, since the DAOs client is the EJB service layer, future methods would have to repeat this logic.
What I'd like to do is have the domain objects use the DAOs directly. That is have the domain object implement the DAO interface and have its concrete implementation invoke the DAO method itself. That's a mouthful, so here's an example:
The Case domain class would now implement CaseDAO (generic DAO interface) and fulfill the contract by implementing the required methods:
Code:
public class Case extends SpotLightDomain implements CaseDAO {
...
/**
* Find a case by id
*/
public Case findCaseById(String id) {
return getDAOFactory().getCaseDAO().findCaseById(String id);
}
public Case save(Case aCase) {...}
...
}
Our service layer method has now been simplified. The Case object finds itself and is only assembled into a DTO (I know DTOs are ugly -- but in this case required) here.
Code:
public CaseDTO getCase(String id)
throws SpotLightException {
CaseDTO dto = null;
prepareSession();
try {
dto = CaseAssembler.writeDTO(new Case().findCaseById(id);
}
catch (Exception e) {
getSessionContext().setRollbackOnly();
throw (SpotLightException) SpotLightExceptionConverter.convert(e);
}
finally {
closeSession()
}
return dto;
}
We've decoupled our service layer from our DAO and data source layer, amortized the persistence logic across service methods, and avoid transaction script-style logic.
The domain and DAO are loosely coupled via the use of our factory strategy.
Are others doing something similar? Any comments appreciated.
Regards,
Roll