异常后丢失 EntityManager
Losing EntityManager after Exception
我正在尝试使用异常来处理用户输入的名称超过特定字符数的情况。如果发生异常,我会将其捕获为 PersistenceException 并将信息提供给用户。
EntityManagerFactory emf=(EntityManagerFactory)getServletContext().getAttribute("emf");
EntityManager em = emf.createEntityManager();
try
{
String name = request.getParameter("name");
if(name != null)
{
em.getTransaction().begin();
em.persist(new Guest(name));
em.getTransaction().commit();
}
...
}
catch(PersistenceException e)
{
request.setAttribute("valid", false);
}
但是在通知用户之后,我仍然需要列出之前输入到db的所有名称,但是在以下段中:
finally
{
List<Guest> guests= em.createQuery("SELECT g FROM Guest g",Guest.class).getResultList(); }
我得到:
org.hibernate.AssertionFailure: null id in com.guest.Guest entry (don't flush the Session after an exception occurs)
当我通过重新创建 entityManager 将 "finally" 部分更改为跟随时,我没有收到错误。
finally{
em = emf.createEntityManager();
List<Guest> guests= em.createQuery("SELECT g FROM Guest....}
我还用 Eclipse 调试器检查了 EntityManager 是否正常,我得到了以下信息:
所以,即使我的 EntityManager 没问题,为什么我需要重新创建它才不会出现该错误?
与您的问题无关,但很明显,您尝试在 finally
子句中执行的 SQL 查询不属于该方法。您正在混合两个 "behaviors".
您可以使用只保存实体的实际方法,然后使用另一个名称更有意义的方法来检索 guests
;所以你将不得不调用数据库(就像你现在所做的那样),但你不会有那种奇怪的行为,因为你只是 "separate the concerns".
顺便说一句,该错误可能与您提交(或未提交)更改有关(不确定,只是猜测)并且涉及异常,因此您的 Hibernate 会话可能会丢失。
更新: 查看来自 JB Nizet 的答案。
If the Session throws an exception, including any SQLException, immediately rollback the database transaction, call Session.close() and discard the Session instance. Certain methods of Session will not leave the session in a consistent state. No exception thrown by Hibernate can be treated as recoverable.
我正在尝试使用异常来处理用户输入的名称超过特定字符数的情况。如果发生异常,我会将其捕获为 PersistenceException 并将信息提供给用户。
EntityManagerFactory emf=(EntityManagerFactory)getServletContext().getAttribute("emf");
EntityManager em = emf.createEntityManager();
try
{
String name = request.getParameter("name");
if(name != null)
{
em.getTransaction().begin();
em.persist(new Guest(name));
em.getTransaction().commit();
}
...
}
catch(PersistenceException e)
{
request.setAttribute("valid", false);
}
但是在通知用户之后,我仍然需要列出之前输入到db的所有名称,但是在以下段中:
finally
{
List<Guest> guests= em.createQuery("SELECT g FROM Guest g",Guest.class).getResultList(); }
我得到:
org.hibernate.AssertionFailure: null id in com.guest.Guest entry (don't flush the Session after an exception occurs)
当我通过重新创建 entityManager 将 "finally" 部分更改为跟随时,我没有收到错误。
finally{
em = emf.createEntityManager();
List<Guest> guests= em.createQuery("SELECT g FROM Guest....}
我还用 Eclipse 调试器检查了 EntityManager 是否正常,我得到了以下信息:
所以,即使我的 EntityManager 没问题,为什么我需要重新创建它才不会出现该错误?
与您的问题无关,但很明显,您尝试在 finally
子句中执行的 SQL 查询不属于该方法。您正在混合两个 "behaviors".
您可以使用只保存实体的实际方法,然后使用另一个名称更有意义的方法来检索 guests
;所以你将不得不调用数据库(就像你现在所做的那样),但你不会有那种奇怪的行为,因为你只是 "separate the concerns".
顺便说一句,该错误可能与您提交(或未提交)更改有关(不确定,只是猜测)并且涉及异常,因此您的 Hibernate 会话可能会丢失。
更新: 查看来自 JB Nizet 的答案。
If the Session throws an exception, including any SQLException, immediately rollback the database transaction, call Session.close() and discard the Session instance. Certain methods of Session will not leave the session in a consistent state. No exception thrown by Hibernate can be treated as recoverable.