Java 尝试捕获持久异常
简单的问题。代码如下:Java 尝试捕获持久异常,java,mysql,jpa,Java,Mysql,Jpa,简单的问题。代码如下: public void insertDefacer(Defacer defacer) { try { em.persist(defacer); } catch (PersistenceException | DatabaseException e) { defacer = em.find(Defacer.class, defacer.getIdentity()); defacer.setStats(defac
public void insertDefacer(Defacer defacer) {
try {
em.persist(defacer);
} catch (PersistenceException | DatabaseException e) {
defacer = em.find(Defacer.class, defacer.getIdentity());
defacer.setStats(defacer.getStats() + 1);
em.merge(defacer);
}
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void insertDefacer(Defacer defacer) {
Defacer df = em.find(Defacer.class, defacer.getIdentity());
if(df == null) {
em.persist(defacer);
System.out.println("Save");
} else {
em.merge(defacer);
System.out.println("Update");
}
当数据库(mysql)中已经存在defacer时,persist
操作抛出异常(PersistenceException
和/或DatabaseException
)。这似乎很正常。所以我想抓住这些异常并威胁它们。但是在记录这些异常之后,我的程序突然结束(没有完成方法)
为什么?
详细信息(可能很重要,也可能不重要):em是否是一个EntityManager通过@PersistenceContext您是否尝试通过这种方式获取EntityManager
@PersistenceContext
private EntityManager em;
public EntityManager getEntityManager() {
return em;
}
public void setEntityManager(EntityManager em) {
this.em = em;
}
您不应该在
catch
子句中使用EntityManager
,因为它可能处于损坏状态。JPA中的异常是不可恢复的,因此您应该假设,如果发生异常,您的事务将无法完成
public void insertDefacer(Defacer defacer) {
EntityTransaction tx = null;
try {
tx = em.getTransaction();
tx.begin();
em.persist(defacer);
tx.commit();
} catch (Exception ex) {
if(tx != null && tx.isActive()) tx.rollback();
} finally {
em.close();
}
}
我找到了另一个选择。只需查看代码:
public void insertDefacer(Defacer defacer) {
try {
em.persist(defacer);
} catch (PersistenceException | DatabaseException e) {
defacer = em.find(Defacer.class, defacer.getIdentity());
defacer.setStats(defacer.getStats() + 1);
em.merge(defacer);
}
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void insertDefacer(Defacer defacer) {
Defacer df = em.find(Defacer.class, defacer.getIdentity());
if(df == null) {
em.persist(defacer);
System.out.println("Save");
} else {
em.merge(defacer);
System.out.println("Update");
}
}
正如我所说,这是一个缓和的解决办法。感谢您的帮助。确保PersistenceException属于hibernate软件包 你从哪里调用finish方法?我希望我的catch运行。但事实并非如此。我怀疑在您的
catch
块中发生了另一个异常。通常情况下,您的程序应该继续运行,因此您的EntityManager
可能发生了一些事情来防止这种情况。哦,好吧,捕获它没有执行,同意@TimBiegeleisen。等2分钟,伙计们,我测试@TimBiegeleisen的解决方案。看起来不错。如果persist有效,代码将执行merge。我不想这样。我不明白,为什么你认为在得到EntityManager后,事情会有所不同?我需要解释。