简体   繁体   中英

Spring, add one column to an existing Many to Many list in one query

I have a Project entity which has the following attribute:

  @ManyToMany
  @JoinTable(
          name = "employee_projects",
          joinColumns = @JoinColumn(name = "project_id"),
          inverseJoinColumns = @JoinColumn(name = "employee_id")
  )
  private List<Employee> employees;

Im executing the following service method when im adding another employee to employees .

  Employee addEmployeeToProject(long id, Employee employee) {
    Project project = findByProjectId(id);
    List<Employee> oldEmployees = project.getEmployees();
    oldEmployees.add(employee);
    project.setEmployees(oldEmployees);
    projectRepository.save(project);
    return employee;
  }

That works fine. But then i actually started logging SQL requests and thats what actually happens:

2019-12-17 18:45:52.644 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : delete from employee_projects where project_id=?
2019-12-17 18:45:52.646 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.648 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.648 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.650 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.650 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.651 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.651 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.651 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.652 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.652 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.652 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.652 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.653 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.653 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)
2019-12-17 18:45:52.653 DEBUG 14324 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into employee_projects (project_id, employee_id) values (?, ?)

So he first of all deletes all of the columns(removes all employees from the given project). And then adds all previous ones + the new one in again. I guess thats what happens if im replacing the entire collection. But i only need to insert one object so to save time i could just write my own insert query so it only inserts that one new employee i want to insert instead of deleting everything and adding everything in again. But is there a better way to do it in one request/query besides writing an own query?

EDIT:

Can i only define INSERT queries if i use native queries? Isnt it possible in JPQL?

Sure. First, start by doing all this in a single transaction, and thus benefit from the fact that modifications to a managed entity are automatically persisted. No need to cal save() .

Then, understand that Java passes references to objects. If you get the collection of employees of aproject, you don't get a copy of the collection. You get a reference to it. So adding an employee to that collection effectively modifies the collection of employees of the project. No need to set the collection again in the project.

So finally, all you need is

@Transactional
public void addEmployeeToProject(long id, Employee employee) {
    Project project = findByProjectId(id);
    project.getEmployees().add(employee);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM