Jersey, Guice and Hibernate - EntityManager thread safety

泄露秘密 提交于 2019-12-01 14:13:13

First of all, what kind of EntityManager are you using? Looking at your code I suposse this kind is Application-Managed EntityManager. It would be important for you to understand the different types of EntityManager.

Please see: http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html

Basing on this, you need to create an EntityManagerFactory object and then create an EntityManager object.

Basic Example:

private static EntityManagerFactory emf; 
EntityManager em = null;

public static EntityManagerFactory getEmf(){
    if(emf == null){
        emf = Persistence.createEntityManagerFactory("nameOfYourPersistenceUnit");
    }
    return emf;
}


em = getEmf().createEntityManager();
em.getTransaction().begin();
em.persist(entity);
em.getTransaction().commit();
em.close();

The problem was that my endpoint was annotated with @Singleton so it reused the same EntityManager during concurrent calls. After removing @Singleton, during concurrent calls, different EntityManager objects are used. If endpoint calls are subsequent, it may be that previous/old EntityManager will be used.

Highly simplified example:

@Path("/v1/items")
public class ItemsService {

    @Inject
    private EntityManager entityManager;

    @POST
    @Path("/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public void saveItem(){
         entityManager.getTransaction().begin();
         entityManager.persist(new Item());
         entityManager.getTransaction().commit();
    }
}

If it says that the transaction is already open, that means that it was open by another process and not closed ...

I suggest to use @Transactionl instead of Writing :

em.getTransaction().begin();

and

em.getTransaction().commit();
em.close();

That will manage the things for you ...

so for you it will be this way :

@Transactionl
@POST
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public void saveItem(){
     entityManager.persist(new Item());
}

Hope that's help

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!