使用JPA唯一约束丢失交易? [英] Lost transaction with JPA unique constraint?

查看:113
本文介绍了使用JPA唯一约束丢失交易?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a field with an unique constraint:

@Column(unique=true)
private String uriTitle;

当我尝试保存两个具有相同值的实体时,出现一个异常-但另一个异常我期望:

When I try to save two entities with the same value, I get an exception - but another exception than I exected:

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是这样的:

... and the ThreadLocalEntityManager like this:

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 来处理唯一约束冲突,但这不起作用:

I wrapped the call to save with try ...catch to handle the unique constraint violation, but that doesn't work:

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

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

Any idea why there is no transaction? What is the correct way to handle a unique constraint violation?

推荐答案

您的事务由于违反数据库约束而自动回滚,因此存在没有要手动回滚的事务。要处理这种情况,您可以编写

Your transaction rolled back automatically due to DB constraint violation, therefore there is no transaction to rollback manually. To handle this case, you can write

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

这篇关于使用JPA唯一约束丢失交易?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆