Java JPA合并例外

Java JPA合并例外,java,hibernate,jpa,Java,Hibernate,Jpa,为什么JPA不在我进行合并的方法中抛出唯一约束冲突的异常?相反,我看到一个异常在代码的其他地方抛出 我想获得异常消息,如(更新错误),但它无法捕获异常 我希望得到以下回应: { "errorMessage": "Update Error", "errorCode": 404, "documentation": "" } 相反,在控制台中,我得到了以下错误: Caused by: javax.ejb.EJBTransactionRolledbackException: T

为什么JPA不在我进行合并的方法中抛出唯一约束冲突的异常?相反,我看到一个异常在代码的其他地方抛出

我想获得异常消息,如(更新错误),但它无法捕获异常

我希望得到以下回应:

{
    "errorMessage": "Update Error",
    "errorCode": 404,
    "documentation": ""
}
相反,在控制台中,我得到了以下错误:

Caused by: javax.ejb.EJBTransactionRolledbackException: Transaction rolled back
.....
...
Caused by: javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.
.....
.....
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
......
.....
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (DEMAND_TD_CODE) violated
.....
....
以下是我进行更新的地方:

@Override
    public Demand updateDemand(Demand demand) throws DemandExceptions {
        try {
            Demand demandToUpdate = entityManager.merge(demand);
        } catch (PersistenceException e) {
            throw new DemandExceptions("Update Error");
        }
            return demandToUpdate;
    }
DemandeExceptions.java

public class DemandeExceptions extends Exception implements Serializable {
    private static final long serialVersionUID = 1L;
    public DemandeExceptions (String message) {
        super(message);
    }
}

@Provider
public class DemandExceptionsMapper implements ExceptionMapper<DemandeExceptions >{

    @Override
    public Response toResponse(DemandeExceptions ex) {
        ErrorMessage errorMessage = new ErrorMessage(ex.getMessage(), 404, "");
        return Response.status(Status.NOT_FOUND)
                .entity(errorMessage)
                .build();
    }

}

以下是可能导致错误的一些问题:

  • 检查事务关闭后是否捕获异常
  • 检查您使用的类PersistenceException是否正确(检查包)

异常实际上会被捕获,但是您丢失了原始消息,考虑更新catch块如下:

throw new DemandExceptions("Update Error, original message: " + e.getMessage());

为了提高性能,大多数JPA实现缓存DB操作,而不是在每次JPA方法调用时命中DB。这意味着,当您调用
merge()
时,更改将记录在JPA实现正在管理的Java数据结构中,但数据库中尚未发生更新

JPA实现不会检测到诸如唯一约束冲突之类的问题,而这些问题留给数据库处理

这意味着捕获PersistenceException的try块中不会发生唯一约束冲突。相反,当JPA决定需要刷新数据库更新时,会引发异常。这种自动刷新通常在事务提交时发生,但可能发生得更快(例如,如果需要对更新的表执行查询)

您可以通过调用
EntityManager.flush()
手动刷新JPA状态。如果您在try块中执行此操作,您将在您认为应该的位置获得PersistenceException

    try {
        Demand demandToUpdate = entityManager.merge(demand);
        entityManager.flush();
    } catch (PersistenceException e) {
        throw new DemandExceptions("Update Error: " + e.getMessage());
    }

违反了唯一约束(需求代码)。所以,修复为什么会违反它…我在数据库中定义了它,就像unique一样,我试图添加一个实体,用相同的代码进行测试,所以这是一个测试,你只是想检测它?因此,请查找一个PersistenceException,其原因异常为SQLIntegrityConstraintViolationException。请使用:
import javax.persistence.PersistenceContext,是的,它是正确的,您应该在事务后捕获javax.persistence.PersistenceException.close()。试着调试代码,检查你是否真的抛出了你的自定义异常嗯,是的,但我不能得到这个消息,这是我的问题
    try {
        Demand demandToUpdate = entityManager.merge(demand);
        entityManager.flush();
    } catch (PersistenceException e) {
        throw new DemandExceptions("Update Error: " + e.getMessage());
    }