在JPA + Spring中异常后回滚事务

时间:2011-02-22 19:39:08

标签: java hibernate spring jpa

我正在使用Spring和JPA以及HIbernate。抛出PersistenceException时,我想捕获它并返回错误消息,以便它不会传播到调用者。

@Transactional
public String save(Object bean) {
    String error = null;

    try {
        EntityManager entityManager = getEntityManager();

        for (int i = 0, n = entities.size(); i < n; i ++) {
            entityManager.merge(entities.get(i));
        }
    }
    catch (PersistenceException e) {
        error = e.getMessage();
    }

    return error;
}

但是我得到一个异常说javax.persistence.RollbackException: Transaction marked as rollbackOnly.我知道事务需要在异常后回滚但是当我捕获异常并且不想重新抛出时如何回滚它它?

4 个答案:

答案 0 :(得分:5)

您可以将Spring的Exception Translation与自定义PersistenceExceptionTranslator结合使用,将PersistenceException翻译成有用的内容。

哦,顺便说一句,你不应该在DAO级别使用@Transactional。交易应该在服务级别开始。

答案 1 :(得分:4)

如果方法中抛出任何RuntimeExceptions,则使用@Transactional,它将自动执行回滚。您无需手动执行此操作。您可能根本不应该捕获该异常,而是让它传递给更高级别的ExceptionHandler,它向用户显示一些标准错误页面(而不是堆栈跟踪)。此外,您的方法标记为void,但您返回的是String。

答案 2 :(得分:2)

似乎无法回滚Spring ORM管理的失败事务。问题中显示的代码是服务类。将其持久性例程提取到一个单独的DAO类并使服务类句柄PersistenceExceptions成功了。

答案 3 :(得分:0)

对抛出异常的方法使用@Transactional(noRollbackFor={PersistenceException.class})