【发布时间】:2015-06-14 00:58:19
【问题描述】:
我一直在使用 DAO 模式来提供对我正在构建的应用程序中的持久层的访问。
为了验证的目的,我已经实现了一个围绕我的 DAO 实现的“包装器”。包装器接受我的 DAO 的一个实例作为构造函数参数,并实现与 DAO 类似的接口,但异常是抛出的异常类型。
例如:
业务逻辑接口
public interface UserBLInt {
private void assignRightToUser(int userId, int rightId) throws SomeAppException;
}
DAO 接口
public interface UserDAOInt {
private void assignRightToUser(int userId, int rightId) throws SomeJPAExcption;
}
业务逻辑实现
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 实现
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();
}
}
这只是一个简单的示例,但我的问题是,在添加 Right 之前,在 DAO 实现中进行另一次检查以确保 User 不为空似乎是“多余的”,但是,如程序员,我看到了空指针的机会。
显然,我可以在实体管理器上调用 find 后添加一个空检查,如果返回 null,则抛出异常,但这是将 DAO 包装在业务逻辑实现中的全部目的,以预先完成所有验证工作,这样 DAO 代码是干净的,并且根本不需要做太多的空检查或逻辑。既然我有 DAO 的包装器,那么在 DAO 中进行空值检查仍然是一个好主意吗?我知道理论上可以在业务逻辑调用和 dao 调用之间删除对象,这不太可能,并且检查 null 似乎是重复的工作。在这种情况下,最佳做法是什么?
编辑:
这看起来像一个合适的 DAO 修改吗?
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();
}
【问题讨论】: