容器管理实体管理器持久化上下文的范围

时间:2014-08-25 10:23:55

标签: java jpa entity persistence

我有两个实体和一个会话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.find()之前不会出现在entityManager.refresh(manager)中。我有一种关于持久化上下文的范围和生命周期的感觉,我想找出有关它的详细信息。

如果有人能回答这个问题我真的很感激。

谢谢, 彼得。

1 个答案:

答案 0 :(得分:0)

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

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

我怀疑发生的事情是,您传递给Manager的{​​{1}}实例未被分离。它似乎附加到持久性上下文它已过时(因为它没有最新的searchDepartmentByManager(...)(s))。

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