简体   繁体   中英

Losing EntityManager after Exception

I am trying to use Exceptions to handle a case where user have entered a name longer than a certain number of characters. If an exception occurs, I catch it as a PersistenceException and give info to user.

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

But after informing the user, I still need to list all names that are entered to db before, but in the following segment:

    finally
    {
        List<Guest> guests= em.createQuery("SELECT g FROM Guest g",Guest.class).getResultList(); }

I get:

  org.hibernate.AssertionFailure: null id in com.guest.Guest entry (don't flush the Session after an exception occurs)

When I change "finally" part to following by recreating entityManager, I don't get an error.

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

I also checked it with Eclipse debugger to see if EntityManager is ok, and I got the following:

在此处输入图片说明

So, even my EntityManager is ok, why do I need to create it again to not have that error ?

The documentation is clear about it:

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.

Unrelated with your issue, but clearly the SQL query your are trying to execute in the finally clause doesn't belong to that method. You are mixing two "behaviors".

You can use the actual method that you have to ONLY save the entity and then use another one with a more meaningful name to retrieve the guests ; so you would have to database calls (as you have now), but you won't have that weird behavior because you just "separate the concerns".

BTW, the error might be related to the fact that you commit (or not) the changes (not sure, just a guess) and there is an exception involved, so your Hibernate session might be lost.

UPDATE: See the answer from JB Nizet .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM