I have been using a DAO pattern to provide access to my persistence tier in an application that I have been building.
One of the things that I have implemented is a 'wrapper' around my DAO implementations for purposes of validation. The wrapper takes in an instance of my DAO as a constructor parameter, and implements a similar interface as the DAO, with the exception being the types of exceptions thrown.
For example:
Business Logic Interface
public interface UserBLInt {
private void assignRightToUser(int userId, int rightId) throws SomeAppException;
}
DAO Interface
public interface UserDAOInt {
private void assignRightToUser(int userId, int rightId) throws SomeJPAExcption;
}
Business Logic Implementation
public class UserBLImpl implements UserBLInt {
private UserDAOInt userDAO;
public UserBLImpl(UserDAOInt userDAO){
this.userDAO = userDAO;
}
@Override
private void assignRightToUser(int userId, int rightId) throws SomeAppException{
if(!userExists(userId){
//throw an exception
}
try{
userDAO.assignRightToUser(userId, rightId);
} catch(SomeJpAException e){
throw new SomeAppException(some message);
}
}
}
DAO Implementation
public class UserDAOImpl implements UserDAOInt {
//......
@Override
public void assignRightToUser(int userId, int rightId){
em.getTransaction().begin();
User userToAssignRightTo = em.find(User.class, userId);
userToAssignRightTo.getRights().add(em.find(Right.class, rightId));
em.getTransaction().commit();
}
}
This is just a quick example, but my question is, it seems 'redundant' within the DAO implementation to do another check to be sure that the User
isn't null before adding a Right
, but, as a programmer, I see an opportunity for a null pointer.
Obviously I could add a null check after calling find on the entity manager and throw an exception if null is returned, but that's the whole purpose of having the DAO wrapped in a business logic implementation, to do all the validation work beforehand, so that the DAO code is clean and doesn't have to do much in the way of null checks or much logic at all. Since I have the wrapper around the DAO, is it still a good idea to do the null checking anyway in the DAO? I know in theory the object could be deleted between the business logic call and the dao call, it's just unlikely, and checking for null seems like duplicated work. What is the best practice for a situation like this?
EDIT:
Does this look like a suitable DAO modification?
public EntityManager beginTransaction(){
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
return entityManager;
}
public void rollback(EntityManager entityManager){
entityManager.getTransaction().rollback();
entityManager.close();
}
public void commit(EntityManager entityManager){
entityManager.getTransaction().commit();
entityManager.close();
}