【问题标题】:JPA Spring Boot Hibernate Rest API: Why does Hibernate delete before when insert into?JPA Spring Boot Hibernate Rest API:为什么Hibernate在插入之前会删除?
【发布时间】:2021-04-02 04:11:06
【问题描述】:

我想描述以下场景: 我使用 Spring Boot 作为后端,使用 MySQL 数据库和 Angular 9 作为前端。

员工和预订之间是多对多关系。

MySQL

员工:

emp_id name
1 test

预订:

book_id attribute
1 test

book_emp:

emp_id book_id
1 1

到目前为止一切正常,但是当我将更多值发布到链接表时,所有其他元组都被删除。

book_emp:

emp_id book_id
1 2

结果应该是这样的:

emp_id book_id
1 1
1 2

控制台

Hibernate: insert into booking (hours, total, wadge_eur, year) values (?, ?, ?, ?)
Hibernate: delete from book_emp where emp_id=?
Hibernate: insert into book_emp (emp_id, book_id) values (?, ?)

为什么 Hibernate 从 book_emp 中删除?我已经尝试了 ManyToMany 注释类中所有可能的变体。不幸的是没有成功。我认为问题出在 RestController。

我之前试过 PUT,但结果和 POST 一样。

春季启动 Employee.java

@ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
    @JoinTable(name = Constant.BOOK_EMP, joinColumns = @JoinColumn(name = Constant.EMP_ID, referencedColumnName = Constant.EMP_ID), 
            inverseJoinColumns = @JoinColumn(name = Constant.BOOK_ID, referencedColumnName = Constant.BOOK_ID), 
            uniqueConstraints = {
            @UniqueConstraint(columnNames = { Constant.EMP_ID, Constant.BOOK_ID }) 
            })
    @JsonBackReference(value = Constant.BOOKING)
    private Set<Booking> bookings;

Booking.java

@ManyToMany(mappedBy = "bookings")
       private Set<Employee> employees;

EmployeeController.java:

@PostMapping(Constant.EMPLOYEE + "/{id}")
    public Employee postEmployeeById(@PathVariable(value = "id") Long employeeId,
            @Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException {
        Employee employee = employeeRepository.findById(employeeId)
                .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id ::" + employeeId));
                
        employee.setBookings(employeeDetails.getBookings());
                
        return employeeRepository.save(employee);

EmployeeRepository.java

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {}

角度 员工服务.ts

  updateEmployeeData(id: number, value: any): Observable<Object> {
    return this.httpClient.post(`${this.baseURL + this.empURL}/${id}`, value);
  }

如何让 Hibernate 停止删除?

【问题讨论】:

  • 但这就是你要求它做的事情:employee.setBookings(employeeDetails.getBookings());。在应用新关联之前,它首先必须删除旧关联。
  • 我应该问什么?
  • 好吧,您的预订集合似乎已在客户端更新。因此,在这种情况下,id 为 1 的预订将被删除,因此您只剩下预订 2。

标签: angular spring-boot hibernate rest jpa


【解决方案1】:

[分辨率]

员工类

//LOMBOK 
...
@EqualsAndHashCode(exclude = "bookings")
...

    @ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
        @JoinTable(name = Constant.BOOK_EMP, joinColumns = @JoinColumn(name = 
         Constant.EMP_ID, referencedColumnName = Constant.EMP_ID, updatable = false, 
         insertable = false), 
            inverseJoinColumns = @JoinColumn(name = Constant.BOOK_ID, referencedColumnName = Constant.BOOK_ID, updatable = false, insertable = false), 
            uniqueConstraints = {
            @UniqueConstraint(columnNames = { Constant.EMP_ID, Constant.BOOK_ID }) 
            })
    @JsonBackReference(value = Constant.BOOKING)
    private Set<Booking> bookings;
    
    @JsonIgnore
    public boolean addEmpBook(Set<Booking> set) {
            return this.bookings.addAll(set);           
    }

预订舱位

//LOMBOK: 
...
@EqualsAndHashCode(exclude = "employees")
...
    
    @JsonIgnore
    @ManyToMany(mappedBy = "bookings")
    private Set<Employee> employees;

员工控制器

    @PostMapping(Constant.EMPLOYEE + "/{id}")
    public Employee postEmployeeById(@PathVariable(value = "id") Long employeeId,
            @Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException {
        Employee employee = employeeRepository.findById(employeeId)
                .orElseThrow(() -> new ResourceNotFoundException("Employee not found for 
                this id ::" + employeeId));
        
        employee.addEmpBook(employeeDetails.getBookings());
        return employeeRepository.save(employee);
    }
    

控制台休眠

Hibernate: insert into booking (hours, total, wadge_eur, year) values (?, ?, ?, ?)
Hibernate: insert into book_emp (emp_id, book_id) values (?, ?)

【讨论】:

    猜你喜欢
    • 2020-11-24
    • 2017-11-20
    • 2022-01-06
    • 2020-12-27
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    相关资源
    最近更新 更多