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

JPA:如何在不创建新对象的情况下更改引用id,jpa,eclipselink,many-to-one,Jpa,Eclipselink,Many To One,例如,我有一个引用部门的实体雇员 @ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.MERGE}) private Department department; 我想拯救新员工,但我已经知道部门id是9L。现在我把它保存起来 em.getTransaction().begin(); final Employee emp = new Employee();

例如,我有一个引用部门的实体雇员

@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

是否可以在不创建新部门对象的情况下设置员工实例的部门id


谢谢。

简短的回答是“否”。您的级联规则要求引用现有部门,否则将创建一个新部门

CascadeType.PERSIST:表示保存或持久化操作级联到相关实体

CascadeType.MERGE:表示合并所属实体时,相关实体合并到托管状态


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

是的,但这是有代价的。您需要将Employee->Department引用设为只读insertable=false,updateable=false,以便向员工添加基本映射,以便直接设置部门ID。然后,您将负责在每种情况下手动设置部门ID,并注意,如果不维护Employee.department引用,它可能会变得不同步。这意味着,如果不设置关系,则在强制刷新之前,即使字段的基本映射具有值,该关系也可能为null

即:

如有需要:

em.refresh(emp);

我还没有用EclipseLink尝试过,但是用设置依赖关系所需的id创建一个新的Department实例就足够了。其次,它将尝试保存新的Department对象,因为它是级联持久的。因此,在本例中,它将使用自动递增的id和空名称创建新的Department对象。谢谢。不,那太复杂了。我知道我可以手动处理该字段。我想找到一种获取department_id的方法,尽管此字段是由manager自动创建的,没有显式的getter或setter。我不太了解您的评论的上下文以及您要查找的内容。我想找到一种获取表的department_id字段并设置其值的方法。此字段由EclipseLink自动创建。事实上,我甚至不知道这个字段有名称department_id,我在数据库中找到了这些信息。我只知道,这个字段是在我设置部门对象的id并将部门设置为员工时设置的。每次2使用您的方法时,有两种方法1创建对象。我想用一种方便的方法来处理模型,但存在一些性能问题。我需要将db请求的数量从6个减少到3个。第三个选项是将对象映射为平面,而无任何关系。如果您知道自己在做什么,这将使您能够更好地控制性能,但由于您需要在需要时手动查找部门,因此会给您带来不便。我的建议是在两者之间架起一座桥梁。
em.refresh(emp);