JPA合并例外

use*_*879 2 java hibernate jpa

在我执行合并的方法中,JPA为什么不为唯一约束违例引发异常?相反,我在代码中看到了引发异常的地方。

我想获取诸如(Update Error)之类的异常消息,但没有捕获到异常。

我想得到这个回应:

{
    "errorMessage": "Update Error",
    "errorCode": 404,
    "documentation": ""
}
Run Code Online (Sandbox Code Playgroud)

相反,在控制台中出现此错误:

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
.....
....
Run Code Online (Sandbox Code Playgroud)

这是我进行更新的地方:

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

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();
    }

}
Run Code Online (Sandbox Code Playgroud)

ErrorMessage.java

@XmlRootElement
public class ErrorMessage {

    private String errorMessage;
    private int errorCode;
    private String documentation;
   ..
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 5

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

JPA实现不会检测到诸如唯一约束违规之类的问题,这些问题留给了数据库。

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

您可以通过调用手动刷新JPA状态EntityManager.flush()。如果在try块中执行此操作,则将获得您原本希望的PersistenceException。

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