java - 丢失具有 JPA 唯一约束的事务?

标签 java exception jpa transactions unique-constraint

我有一个具有唯一约束的字段:

@Column(unique=true)
private String uriTitle;

当我尝试保存具有相同值的两个实体时,我收到一个异常 - 但另一个异常比我执行的要多:

java.lang.IllegalStateException: <|Exception Description: No transaction is currently active
        at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.rollback(EntityTransactionImpl.java:122)
        at com.example.persistence.TransactionFilter.doFilter(TransactionFilter.java:35)

有问题的过滤方法如下所示:

public void doFilter(ServletRequest request, ServletResponse response,
          FilterChain chain)
          throws IOException, ServletException {
    EntityManager entityManager = ThreadLocalEntityManager.get();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    try {
      chain.doFilter(request, response);
      transaction.commit();
    }
    catch (Throwable t) {
      transaction.rollback();  // line 35, mentioned in the exception
      throw new RuntimeException(t);
    }
    finally {
      entityManager.close();
      ThreadLocalEntityManager.reset();
    }
}

...和 ​​ThreadLocalEntityManager 像这样:

public class ThreadLocalEntityManager {

    private static EntityManagerFactory entityManagerFactory = null;
    private static final ThreadLocal<EntityManager> entityManager =
        new ThreadLocal<EntityManager>() {
            @Override 
            protected EntityManager initialValue() {
                return entityManagerFactory.createEntityManager();
            }
        };

    private ThreadLocalEntityManager() {}

    public static synchronized void init(String persistenceUnit) {
        requireNotNull(persistenceUnit);
        requireState(entityManagerFactory == null, "'init' can be called only "
                        + "once.");
        entityManagerFactory =
                        Persistence.createEntityManagerFactory(persistenceUnit);
    }

    public static EntityManager get() {
        requireState(entityManagerFactory != null, "Call 'init' before calling "
                        + "'get'");
        return entityManager.get();
    }

    public static void reset() {
        entityManager.remove();
    }

}

我用 try ...catch 包装了对 save 的调用来处理唯一约束违规,但这不起作用:

try {
    ThreadLocalEntityManager.get().persist(article); // article is constrained
}
catch(Throwable t) {
    t.printStackTrace();
}

知道为什么没有交易吗?处理唯一约束违规的正确方法是什么?

最佳答案

由于数据库约束违规,您的事务自动回滚,因此没有需要手动回滚的事务。为了处理这种情况,你可以写

catch (Throwable t) {
  if (transaction.isActive()) 
    transaction.rollback();  // line 35, mentioned in the exception 
  throw new RuntimeException(t); 
}

关于java - 丢失具有 JPA 唯一约束的事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3500096/

相关文章:

java - 如何从android中的帧缓冲区创建一个png图像

java - 在非静态方法中,每次创建对象时都会重复该方法吗?

java - 你能弄清楚为什么这个程序会触发 IllegalStateException 吗?

c# - 畸形字符串异常 Firebird + linq

java - 使用@batchsize 后jpa 性能崩溃

java - 错误 : syntax error at or near "user"

java - 继承使用 Scanner 的 Java 构造函数

java - TCP 服务器疯狂 - 缓慢且合并的数据

java - 尝试提示用户从 catch block 重新输入,但 catch block 终止?

java - 在 Spring-JPA 应用程序中使用 JAXB 访问对象