使用ViewScoped CDI bean扩展持久化上下文

时间:2016-01-25 21:02:51

标签: jpa cdi seam java-ee-7

我是一位长期以来尝试迁移到Java EE7,JSF2.2和CDI的Seam用户。 在Seam中,您倾向于在大多数时间使用扩展范围的EntityManagers(在Seam Conversation Scope中)。你没有得到关于Ajax请求的任何LIE。

我试图以类似的方式使用Java EE7和CDI,但不知何故注入的EntityManager只是事务范围。当我在以前加载的实体中获得ajax请求时不再进行管理。

我在我的CDI bean上使用新的javax.faces.view.ViewScoped和javax.transactional.Transactional。

我的制作人:

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

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

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

因此,当我第一次通过Ajax调用testAdd()时,它会创建一个新的测试实体。当我然后调用testRead()时,它获取所有测试实体并检查最后创建的测试实体是否仍然被管理(如果它是具有扩展持久化上下文的EntityManager,它应该如何)。但是entityManager.contains(lastTest)总是返回false。

我做错了什么?

我相信我不能直接在CDI bean中使用@PersistenceContext。那么我如何获得所需的(Seam like)行为?

1 个答案:

答案 0 :(得分:0)

  

当您指定注入的EntityManager是扩展的持久性上下文时,所有对象实例将保持受管状态。扩展的持久性上下文只能在有状态会话Bean中使用。

这是根据JBOSS文档:https://docs.jboss.org/ejb3/app-server/tutorial/extended_pc/extended.html

考虑将插入/更新/删除操作打包到EJB中,而可以通过CDI Bean轻松地从数据库读取数据。但是,涉及多个读取和写入以及事务的更复杂的操作应该在EJB中。