jpa - JPA:单独更新映射表
问题描述
我有一个 Project 和 Employee 实体,它们具有如下所示的 ManyToMany 关系。
@Entity
public class Project {
@Id @GeneratedValue
private int projectId;
private String projectName;
// has some additional columns
@ManyToMany(mappedBy = "projects")
private List<Employee> emp = new ArrayList<Employee> ();
....
.....
}
@Entity
public class Employee {
@Id @GeneratedValue
private int id;
private String firstName;
private String lastName;
@ManyToMany(cascade=CascadeType.ALL)
List<Project> projects = new ArrayList<Project> ();
....
....
}
当我使用上述实体时,JPA 会创建一个如下所示的 mpping 表“Employee_Project”。
create table Employee_Project (emp_id integer not null, projects_projectId integer not null)
我的问题是,每当添加新员工时,我只想更新员工表和 Employee_Project 映射表,假设我知道我想将此员工映射到的项目 ID。(不接触项目表/实体,我的意思是为什么我要提供完整的项目对象,而单独保存员工实体,我怎么能通过 jpa 做到这一点?)
解决方案
您不需要提供整个Project
对象。使用EntityManager.getReference(projectId)
或JpaRepository.getOne(projectId)
。
这些方法将创建一个具有适当 id 的代理对象,而不是从数据存储中加载整个Project
实体。
编辑您的服务方法应如下所示:
@Transactional
public void createEmployee(Employee employee, Long projectId) {
employee.setProjects(List.of(projectRepository.getOne(projectId));
employeeRepository.save(employee);
}
作为旁注,CascadeType.ALL
(特别是因为它包含CascadeType.MERGE
and CascadeType.REMOVE
)对于@ManyToMany
. 除非您打算Project
通过创建来创建Employee
,否则CascadeType.PERSIST
也没有任何意义。
推荐阅读
- unity3d - 以与 Unity 相同的方式为 Texture2D 着色
- visual-studio - 如何将立方体向一个方向移动 3 秒,然后在相反方向移动 3 秒,或者
- r - 循环更改变量名的一部分并重复该命令
- terraform - Convert list to map with index in Terraform
- python - 在 python 中使用 Regex 将带有某些特定单词或字符(如逗号)的文本分块
- awk - AWK 从 csv 加入接下来的 2 行
- sql - 如何为多个列创建唯一约束?
- c# - 调整窗口大小时,我的按钮不会调整大小
- python - 为什么numpy数组比python中的列表快?
- javascript - 使用 cookie 获取标头