Java 异常后丢失EntityManager

Java 异常后丢失EntityManager,java,hibernate,exception,jpa,entitymanager,Java,Hibernate,Exception,Jpa,Entitymanager,我试图使用异常来处理用户输入的名称超过一定数量字符的情况。若发生异常,我将其作为PersistenceException捕获,并向用户提供信息 EntityManagerFactory emf=(EntityManagerFactory)getServletContext().getAttribute("emf"); EntityManager em = emf.createEntityManager(); try { String name =

我试图使用异常来处理用户输入的名称超过一定数量字符的情况。若发生异常,我将其作为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(); }
当我通过重新创建entityManager将“finally”部分更改为following时,我没有得到错误

   finally{
        em = emf.createEntityManager();
        List<Guest> guests= em.createQuery("SELECT g FROM Guest....}
最后{
em=emf.createEntityManager();
List guests=em.createQuery(“从Guest中选择g…”
我还使用Eclipse调试器检查了EntityManager是否正常,得到了以下结果:


所以,即使我的EntityManager还可以,为什么我需要再次创建它以避免出现错误?

与您的问题无关,但显然您试图在
finally
子句中执行的SQL查询不属于该方法。您混合了两种“行为”

您可以使用实际的方法,只需保存实体,然后使用另一个名称更有意义的实体来检索
来宾
;因此您必须进行数据库调用(正如您现在所做的那样),但您不会有这种奇怪的行为,因为您只需“分离关注点”

顺便说一句,错误可能与您提交(或不提交)更改有关(不确定,只是猜测),并且涉及异常,因此您的Hibernate会话可能会丢失

更新:请参见JB的答案,Nizet

对此很清楚:

如果会话引发异常(包括任何SQLException),请立即回滚数据库事务,调用Session.close()并放弃会话实例。会话的某些方法不会使会话保持一致状态。Hibernate引发的任何异常都不能视为可恢复

   finally{
        em = emf.createEntityManager();
        List<Guest> guests= em.createQuery("SELECT g FROM Guest....}