2

什么时候

  1. 我通过无状态服务从数据库中获取实体,
  2. 然后在另一个bean中修改它并
  3. 然后想通过无状态服务将其保存到数据库中,

我注意到实体已经分离。我认为因为无状态服务的持久化上下文,实体是从被抓住的来的存在的。但是应该使用有状态服务吗?
现在,在保存时,我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)));
    }
}  

bean 日志语句会告诉我,对象已分离:

 @ManagedBean
    @ViewScoped
    public class CategoriesBean implements Serializable {
        private Category testCategory;

        @PostConstruct
        public void init(){
            testCategory = dbs.getCategories().get(0);
            dbs.checkIfDetached(testCategory);
        }
    }
4

3 回答 3

1

分离的实体没什么大不了的,你可以很容易地把它装回去,你知道的。实际上,如果我记得EJB 3 in Action的演讲,JPA 的设计方式就是尽可能地附加实体。

在对其执行任何 JPA 操作之前,只需合并(附加回)您的实体:

em.merge(entity);
于 2013-10-01T11:45:04.717 回答
1

一些原因是:

  1. 您在第 2 步中使用@Remote EJB 而不是@Local。
  2. 第一个 EJB 的事务上下文与第二个不同。

易于理解的是,一旦事务关闭(提交或回滚),实体就会分离。

我没有使用 JSF 的经验,但我认为一旦您在 JSF 中调用 ejb.getCategories(),EJB 中的事务就会完成,因此实体会被分离。你也没有展示你是如何注入数据库的:我希望你是使用@EJB. 此外,我已经读过(至少 @ManagedBean -annotated)JSF 不是(默认?)事务性的。

于 2013-10-01T09:27:37.723 回答
1

这可能是因为当您调用 getCategories 时,由于没有事务而启动了一个新事务。当函数退出时,事务完成并且所有实体都被分离。确保您在单个事务中完成所有步骤。

于 2013-10-01T11:37:14.713 回答