2015-08-13 6 views
1

Я пытаюсь использовать Исключения для обработки случая, когда пользователь ввел имя длиннее определенного количества символов. Если возникает исключение, я воспринимаю его как PersistenceException и предоставляю информацию пользователю.Losing EntityManager после исключения

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); 
    } 

Но после уведомления пользователя, мне еще нужно, чтобы перечислить все имена, которые вводятся в БД раньше, но в следующем сегменте:

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) 

Когда я меняю часть «finally» на следующую, воссоздавая entityManager, я не получаю ошибку.

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

Я также проверил его с Eclipse, отладчик, чтобы увидеть, если EntityManager это нормально, и я получил следующее:

enter image description here

Таким образом, даже мой EntityManager нормально, зачем мне нужно создать он снова не должен иметь эту ошибку?

ответ

2

The documentation ясно об этом:

Если сессия генерирует исключение, в том числе любой SQLException, немедленно откатить транзакцию базы данных, вызовите Session.close() и отбрасывать экземпляр Session. Некоторые методы сеанса не оставляют сеанс в согласованном состоянии. Никакое исключение, вызванное Hibernate, не может рассматриваться как подлежащее восстановлению.

0

Не связанный с вашей проблемой, но ясно, что запрос SQL, который вы пытаетесь выполнить в предложении finally, не относится к этому методу. Вы смешиваете два «поведения».

Вы можете использовать фактический метод, который вы должны ТОЛЬКО сохранить сущность, а затем использовать другой с более значимым именем для получения guests; поэтому вам придется обращаться к вызовам базы данных (как и сейчас), но у вас не будет такого странного поведения, потому что вы просто «разделяете проблемы».

Кстати, ошибка может быть связана с тем фактом, что вы совершаете (или не) изменения (не уверен, просто догадка), и есть исключение, поэтому сеанс Hibernate может быть потерян.

ОБНОВЛЕНИЕ: См. Ответ от JB Nizet.

Смежные вопросы