JPA:如何在不创建新对象的情况下更改引用ID

时间:2015-04-02 12:33:15

标签: jpa eclipselink many-to-one

例如,我有实体Employee引用Department

@ManyToOne(fetch=FetchType.LAZY, 
           cascade={CascadeType.PERSIST, CascadeType.MERGE})    
private Department department;

我想保存新的员工,但我已经知道部门ID(它是9L)。现在我保存它像

em.getTransaction().begin();
final Employee emp = new Employee();            
emp.setFirstName("A");
emp.setLastName("L");
emp.setDepartment(em.getReference(Department.class, 9L));
em.persist(emp);    
em.getTransaction().commit();

所以,每次我需要在DB中找到Department,或者至少从代理中获取对象,然后调用setDepartment

是否可以在不创建新的Department对象的情况下设置Employee实例的department_id?

感谢。

2 个答案:

答案 0 :(得分:0)

简短的回答是否定的。您的级联规则需要引用现有部门,否则将创建新部门。

http://howtodoinjava.com/2014/09/25/hibernate-jpa-cascade-types/

CascadeType.PERSIST:表示save()或persist()操作级联到相关实体。

CascadeType.MERGE:表示在合并拥有实体时,相关实体合并为托管状态。

如果您想避免查找,则需要更改级联规则。

答案 1 :(得分:0)

是的,但需要付出代价。您需要将Employee-> Department引用设置为只读(insertable = false,updatable = false),以允许您向Employee添加基本映射以用于直接设置department_ID。然后,您将负责在每种情况下手动设置部门ID,并注意如果您不维护它,Employee.department引用可能会变得不同步。这意味着如果你没有设置关系,它可能是null,即使该字段的基本映射有一个值,直到你强制刷新。

即:

em.getTransaction().begin();
final Employee emp = new Employee();            
emp.setFirstName("A");
emp.setLastName("L");
emp.setDepartment_id(9L);
em.persist(emp);    
em.getTransaction().commit();

如果需要:

em.refresh(emp);