在 JPA 中更好地处理异常

2022-09-02 13:32:14

我在持久化实体时使用EJB3 / JPA,我对它如何管理我的数据库相关任务感到高兴。我唯一关心的是异常处理。保存实体时的示例代码始终具有这种风格。我在网上读到的大多数教程都有这种风格,也不考虑异常处理。

@Stateless
public class StudentFacade{
    @PersistenceContext(unitName = "MyDBPU")
    private EntityManager em;

    public void save(Student student) {
        em.persist(student);
    }
}

但是我不知道在 EJB 应用程序中处理异常的最佳方法是什么?处理异常时,最好的方法是什么?

其他人就是这样处理异常的吗?在您的会话外观上尝试捕获块?

@Stateless
public class StudentFacade{
    @PersistenceContext(unitName = "MyDBPU")
    private EntityManager em;

    public void save(Student student) {
        try {
            em.persist(student);
        } catch(Exception e) {
            //log it or do something
        }
    }
}

还是让方法引发异常?

public void save(Student student) throws Exception {
    em.persist(student);
}

我不知道我的理解是否正确,因为我仍在学习EJB。谢谢


答案 1

异常处理的想法是在发生任何故障时在单个点执行一些逻辑。try catch 将在您需要处理异常或需要将异常转换为另一个异常的最后一点使用

假设你的应用有很多层,即操作、外观、持久

委托异常在这种情况下,在 Facade 上引发的任何异常都可以被抛出到上面的操作层。在操作中,特定异常将被捕获并使用正确的错误消息进行处理。

//This is in Facade Layer
public void save(Student student) throws AppException{
    //exceptions delegated to action layer

    //call to Persist Layer
}

将常规异常转换为应用异常假设在持久性中你得到和DBException像sqlException。此异常不应作为此类发送到操作或立面层,因此我们捕获特定异常,然后引发新异常(用户为应用程序定义的异常)

//This is in Persist Layer
public void save(Student student) throws AppException{
        //converting general exception to AppException and delegating to Facade Layer

        try{
            em.persist(student);//call to DB. This is in Persist Layer
        }catch(Exception e){
            throw new AppException("DB exception", e)
        }
    }

运行中图层您将在操作中捕获异常,然后在那里处理异常

  //This is in Action layer
  public void callSave(Student student){
            try{
                //call Facade layer
            }catch(AppException e){
               //Log error and handle
            }
    }

答案 2

如果你希望你的方法抛出从em.persistance(...)获得的异常,那么不要用该try/catch块包围该语句(因为这将捕获该块中的每个异常)。

解决此问题的方式取决于应用程序,无论是否已经存在一些遗留代码。在存在遗留代码的情况下,我建议您使用相同的方法(即使在某些情况下它不是速度最佳)来保持一致性。

否则,我建议遵循例外的“经验法则” - 首先应该处理它们,因为你拥有采取行动所需的所有信息,否则就扔掉它们,以便其他人可以处理。(如果将它们丢弃,请确保抛出可以引发的最具体的异常形式(而不是一般异常))。使用 JPA 时处理异常与处理一般 Java 异常没有什么不同。

我希望这是关于例外的足够简单的信息,而不是开始“宗教对话”。


推荐