何时
我注意到该实体已被分离。我认为因为无状态服务的持久化上下文,实体来自于抓住存在。
但是,如果使用有状态服务吗?
现在保存时我使用EntityManager#find(ClassOfDetachedEntity,PrimaryKeyOfDetachedEntity)
来获取对数据库中实体的引用,然后将分离的实体分配给它。
但是这样吗?
在我只复制数据库之前,我只是想修改现有的条目。
更新(显示“分离”问题出现位置的快速示例):
@Stateless
@Log
public class DatabaseService implements Serializable {
@PersistenceContext
EntityManager em;
public List<Category> getCategories() {
return em.createQuery("SELECT c FROM Category c").getResultList();
}
public void checkIfDetached(Object o){
log.info("is detached: " + String.valueOf(!em.contains(o)));
}
}
beans log-statement会告诉我,对象是分离的:
@ManagedBean
@ViewScoped
public class CategoriesBean implements Serializable {
private Category testCategory;
@PostConstruct
public void init(){
testCategory = dbs.getCategories().get(0);
dbs.checkIfDetached(testCategory);
}
}
答案 0 :(得分:1)
有些原因是:
易于理解的是,一旦事务关闭(提交或回滚),实体就会被解除。
我没有使用JSF的经验,但我认为一旦你在JSF中调用ejb.getCategories(),EJB中的事务就会完成,因此实体会被释放。你也没有展示你是如何注入dbs的:我希望你使用@EJB
来做到这一点。此外我已经读过(至少@ManagedBean -annotated )JSF不是(默认?)事务性的。
答案 1 :(得分:1)
这可能发生,因为当您调用getCategories时,因为没有事务而启动了新事务。当函数退出时,该事务已完成且所有实体都已分离。确保您在一次交易中完成所有步骤。
答案 2 :(得分:1)
分离的实体并不是什么大不了的事,你知道,你可以轻松地将其附加回来。实际上,如果我记得从 EJB 3 in Action 中解脱出来,那么JPA的设计应该以尽可能 short 时间附加实体。
在对其执行任何JPA操作之前,只需merge(将其附加)您的实体:
em.merge(entity);