1
votes

I am a long time Seam user who tries to move to Java EE7, JSF2.2 and CDI now. In Seam you tend to use EntityManagers with extended scope most of the time (in the Seam Conversation Scope). You don't get any LIEs on Ajax request etc.

I am trying to do it in a similar way with Java EE7 and CDI but somehow the injected EntityManager is only transaction scoped. When I get a ajax request in the entities that were loaded before are not managed anymore.

I am using the new javax.faces.view.ViewScoped and javax.transactional.Transactional on my CDI bean.

My Producer:

 @PersistenceContext(unitName = "primary", type = PersistenceContextType.EXTENDED)
    private EntityManager entityManager;

    @Produces
    @Default
    @Dependent
    public EntityManager getEntityManager() {
        return entityManager;
    }

And my CDI bean:

@Named
@ViewScoped
@Transactional
public class TestBean implements Serializable{
/**
     * 
     */
    private static final long serialVersionUID = 1L;


    @Inject
    EntityManager entityManager;

    Logger log =  Logger.getLogger(TestBean.class);

    private TestEntity lastTest = null;

    public void testAdd(){
        TestEntity test = new TestEntity();
        test.setVal("Test "+System.currentTimeMillis());
        entityManager.persist(test);
        entityManager.flush();
        log.infov("Created test entity {0}", test);
        lastTest = test;
    }

    public void testRead(){
        List<TestEntity> test = entityManager.createQuery("select t from TestEntity t").getResultList();
        for(TestEntity t: test){
            log.infov("Found {0} managed {1}",t,entityManager.contains(t));
        }
        if(lastTest!=null){
            log.infov("Last Test {0} managed {1}",lastTest,entityManager.contains(lastTest));
        }
    }

So when I first call testAdd() via Ajax it creates a new test entity. When I then call testRead() it gets all test entities and checks that the last created test entity is still managed (which it should if it is an EntityManager with an extended persistent context). But entityManager.contains(lastTest) always returns false.

What am I doing wrong?

I believe I can't use @PersistenceContext directly in the CDI bean. So how do I get the desired (Seam like) behaviour?

1
Is your producer a CDI bean or an EJB?John Ament
The producer is a CDI bean. Never thought about doing the producer in a EJB. I guess that could work. Will tryBen
Deltaspike is of great help for the Java EE 7 beginners coming from Seam. You should try RequestScoped persistence contexts as recommended at deltaspike.apache.org/documentation/…jpangamarca

1 Answers

0
votes

When you specify that an injected EntityManager is an extended persistence context, all object instances remain managed. Extended persistence contexts can only be used within Stateful session beans.

This is according to JBOSS documentation: https://docs.jboss.org/ejb3/app-server/tutorial/extended_pc/extended.html.

Consider packaging your insert/update/delete operations into EJBs while simple read from database can be through CDI beans. But more complex operations involving multiple reads and writes as well as transaction should be within EJBs.