我是一位长期以来尝试迁移到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)行为?
答案 0 :(得分:0)
当您指定注入的EntityManager是扩展的持久性上下文时,所有对象实例将保持受管状态。扩展的持久性上下文只能在有状态会话Bean中使用。
这是根据JBOSS文档:https://docs.jboss.org/ejb3/app-server/tutorial/extended_pc/extended.html。
考虑将插入/更新/删除操作打包到EJB中,而可以通过CDI Bean轻松地从数据库读取数据。但是,涉及多个读取和写入以及事务的更复杂的操作应该在EJB中。