与JPA独特约束的交易丢失?
-
29-09-2019 - |
题
我有一个独特约束的领域:
@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();
}
}
...以及像这样的threadLecalentityManager:
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();
}
}
我把电话包裹了 save
和 try ...catch
处理独特的约束违规行为,但这无效:
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);
}
其他提示
您的应用程序中的交易和GUI之间没有任何分离。一般而言,您将在交易处理方面遇到问题。
不隶属于 StackOverflow