无法捕获由约束违规引起的hibernate异常

时间:2018-03-26 17:14:33

标签: hibernate jpa exception

我已经查看了许多其他关于不捕获异常的问题(包括Can't catch ConstraintViolationException),但没有一个问题与我有同样的问题。

使用RestEasy进行网络连接,使用Hibernate与Postgres db进行链接。

我有一个对象:

@Entity
@Table(uniqueConstraints={@UniqueConstraint(columnNames={"user_id"})})
public class Outcome {

    @Id
    @GeneratedValue
    private Long id;

    @OneToOne
    private User user;

    private String anotherAttribute;
}

db服务通过OutcomeResource.saveOutcome发送结果:

@POST
@Consumes("application/json")
@Transactional
public Response saveOutcome(Outcome outcome){
    try {
        myRepository.save(outcome);
        return Response.ok().build();
    } catch (Exception e) {
        System.out.println("I caught the exception:" + e);
        return Response.status(Response.Status.BAD_REQUEST).build();
    }
}

然后由OutcomeRepository.save保存在db中:

public void save(Outcome outcome) {
    try {
        getEntityManager().persist(outcome);
    } catch (Exception e) {
        System.out.println("No I caught the exception : " + e);
    }
}

当为用户发布并保存第一个结果时,它已成功保存在数据库中。如果发布了第二个结果,则会抛出错误,如预期的那样。

缩短的错误堆栈跟踪是:

javax.persistence.RollbackException: 
   Error while committing the transaction
   Description: The server encountered an unexpected condition that
   prevented it from fulfilling the request.
   Exception: org.jboss.resteasy.spi.UnhandledException:
   javax.persistence.RollbackException: Error while committing the transaction
org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:78)...
Root cause: javax.persistence.RollbackException: 
    Error while committing the transaction...
Root cause: javax.persistence.PersistenceException:
    org.hibernate.exception.ConstraintViolationException: 
    could not execute statement...
Root cause: org.hibernate.exception.ConstraintViolationException: 
    could not execute statement...
Root cause: postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint
    Detail: Key (user_id)=(361) already exists.

我想捕获此错误以返回错误的请求响应。 尽管尝试在堆栈跟踪中捕获通用异常和每种特定类型的异常,但都没有输入catch块。

为什么两种方法都没有捕获异常,怎么可能这样做?

1 个答案:

答案 0 :(得分:2)

之后的研究时间我发现了......

无法捕获异常,因为在方法完成后抛出异常。这是因为服务层方法被标记为@Transactional,因此在该事务结束之前,hibernate不会抛出异常。

如果使用spring:写一个转换异常的抛出后建议显然会让你处理这个问题,但是我还没有对它进行测试。

我还没有找到办法在Guice中处理这个异常,所以会让它处理不当。这在我的情况下是可以的。

良好的信息来源:http://forum.spring.io/forum/spring-projects/data/68995-transaction-manager-appears-to-be-eating-the-runtime-exception