首页 > 解决方案 > 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 做到这一点?)

标签: jpaspring-data-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.MERGEand CascadeType.REMOVE)对于@ManyToMany. 除非您打算Project通过创建来创建Employee,否则CascadeType.PERSIST也没有任何意义。


推荐阅读