K. Siva Prasad Reddy
K. Siva Prasad Reddy

Reputation: 12385

JPA's EntityManager should be RequestScoped?

I am developing a JavaEE6 based web application using JBoss7. In my application I am injecting the EntityManager in my EJBs as:

class ForumServiceEJB
{
    @PersistenceContext(type=EXTENDED)
    private EntityManager em;

}

class TopicServiceEJB
{
    @PersistenceContext(type=EXTENDED)
    private EntityManager em;

}

The problem when I update some data using ForumServiceEJB's EntityManager then the changes are made into DB but TopicServiceEJB's EntityManager is not able to see those changes and the results are always fetched from Cache.

I am using ExtendedPerssisteenceContext as My Entities contain child Entity Collections of Lazy Loading type.

How can I use/Inject EntityManager of type ExtendedPersistenceContext and make different EntityManager in one EJB can still see the changes done by other different EJB EntityManagers?

Somewhere I read EntityManagers should be RequestScoped objects.

public class MyEntityManagerProducers {
 @Produces @RequestScoped 
 public EntityManager createDbEm() {
   return Persistence.createEntityManagerFactory("forumDb").
          createEntityManager();
 }

 public void disposeUdEm(@Disposes EntityManager em) {
   em.close();
 }

Is it the way to go?

Upvotes: 4

Views: 3801

Answers (1)

Adeel Ansari
Adeel Ansari

Reputation: 39907

I am using ExtendedPerssisteenceContext as My Entities contain child Entity Collections of Lazy Loading type.

This is not a good reason to use EXTENDED. I would suggest you to make it default, which is TRANSACTION. And it's good to make your EntityManager request-scoped, or method-scoped, in non-enterprise environment or when using application-managed persistence, as this is not a very heavy object to create. Moreover, neither using application-scoped EntityManager is a good idea, as it is not threadsafe.

Having said that, as you are using JBoss, you should let the container handle the lifecycle of EntityManager, in case you are using JTA. Hence, just inject that with everything default

Note:

Only stateful session beans can have a container-managed, extended entity manager.

Links:

Suggestions:

Your business method should know whether to load the children or not. But that's the ideal case. A number of times we can't say that and completely depends on the user input -- we can't predict that well. Therefore, there are two solutions available,

  1. make a separate AJAX call to load children
  2. Use the filter called open-session-in-view. I would prefer the former.

Links:

Upvotes: 1

Related Questions