【问题标题】:The Scope of the Persistence Context of Container Managed Entity Manager容器管理实体管理器持久化上下文的范围
【发布时间】:2014-10-18 11:28:21
【问题描述】:

我有两个实体和一个会话 bean,如下所示:

@Entity
public class Manager {

    @Id
    private int managerId;
    private String name;
    @OneToMany(mappedBy = "manager")
    private Set<Department> departments;

    //... constructors, getters and setters
}

@Entity
public class Department {

    @Id
    private int departmentId;
    @ManyToOne
    private Manager manager;

    //... constructors, getters and setters

}

@Stateless
public class JPADao {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void addDepartment(Department department) throws Exception { 
        entityManager.persist(department);
    }

    @Override
    public List<Property> getAllDepartments() throws Exception {        
        return entityManager.createNamedQuery("SELECT d FROM Department d").getResultList();
    }

    @Override
    public Set<Department> searchDepartmentByManager(Manager manager) throws Exception {
        manager = entityManager.find(Manager.class, manager.getManagerId());
        manager.getDepartments().size();
        entityManager.refresh(manager); //it won't work if I remove this line

        return manager.getDepartments();
    }

出于测试目的,我手动加载了一些数据库中没有部门的经理。

调用addDepartment()后,成功添加部门并建立关系(部门记录有一个与相应经理关联的fk)。当我调用getAllDepartments() 时,也会显示更改。但是,如果我再次调用addDepartment(),并通过传递一个分离的经理对象来调用searchDepartmentByManager(),则entityManager.find() 返回的经理对象将不包含刚刚添加的部门。只有在调用entityManager.refresh(manager) 时,它才会意识到更改。

我不明白的是,为什么entityManager.find() 不返回带有最新数据的经理?我在数据库中检查了调用addDepartment()searchDepartmentByManager() 之间的情况,并且当时成功添加了部门对象。在调用entityManager.refresh(manager) 之前,它不会以某种方式出现在entityManager.find() 中。我感觉它与持久性上下文的范围和生命周期有关,我想了解有关它的详细信息。

如果有人能回答这个问题,我将不胜感激。

感谢, 彼得。

【问题讨论】:

    标签: java jpa entity persistence


    【解决方案1】:

    对于entityManager.find(...),如果Manager 实体实例包含在持久性上下文中,则从那里返回。

    对于entityManager.refresh(...)Manager 实体实例将被数据库中的值覆盖。

    我怀疑正在发生的是您传递给searchDepartmentByManager(...)Manager 实例没有分离。它似乎附加到持久性上下文并且它已过时(因为它没有最新的Department(s))。

    您可以尝试以正确的顺序持久化/合并实体,以维护映射的父子责任。这在here 上进行了描述。 (请注意,该链接讨论的是一对一关系,但该解决方案应适用于所有类型的双向关系)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-13
      • 2012-03-23
      • 1970-01-01
      • 2013-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多