Java 异常后丢失EntityManager
我试图使用异常来处理用户输入的名称超过一定数量字符的情况。若发生异常,我将其作为PersistenceException捕获,并向用户提供信息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 =
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....}