首页 > 解决方案 > @OneToOne 映射删除然后插入而不是更新

问题描述

我已经编写了一些内部具有一对一关系的 Spring Boot 实体。例如:

Student实体

@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "student")
private StudentClub studenttClub;

StudentClub实体

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "student_id", insertable = false, updatable = false)
private Student student;

当我尝试使用存储库更新一些学生俱乐部信息(即 club_code).saveStudent,它会删除然后插入更新的数据。

休眠:从 student_club 中删除 club_code=? 和 student_id=?

Hibernate:插入 student_club (club_code, student_id) 值 (?,?)

我们可以通过仅 1 个语句来完成它,例如

休眠:更新...

标签: javaspring-boothibernate

解决方案


在 StudentClub 实体上移动 @JoinColumn

@Entity
@Table(name = "STUDENT")
public class StudentEntity {
    @Id
    @SequenceGenerator(name = "StudentGen", sequenceName = "STUDENT_SEQ", allocationSize = 1)
    @GeneratedValue(generator = "StudentGen", strategy = GenerationType.SEQUENCE)
    @Column(name = "ID", unique = true)
    protected Long id;

    @OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
    @JoinColumn(name = "CLUB")
    public StudentClubEntity club;
}


@Entity
@Table(name = "STUDENT_CLUB")
public class StudentClubEntity {
    @Id
    @SequenceGenerator(name = "StudentClubGen", sequenceName = "STUDENT_CLUB_SEQ", allocationSize = 1)
    @GeneratedValue(generator = "StudentClubGen", strategy = GenerationType.SEQUENCE)
    @Column(name = "ID", unique = true)
    protected Long id;


    @Column(name = "NAME")
    public String name = "";

    @OneToOne(fetch = FetchType.LAZY)
    public StudentEntity student;
}

尝试测试...

@Test
public void test() {
    System.out.println("test");

    StudentEntity student = new StudentEntity();
    StudentClubEntity club = new StudentClubEntity();

    student.club = club;

    System.out.println("*****************************");
    student = studentRepository.saveAndFlush(student);

    student.club.name = "NEW NAME";
    student = studentRepository.saveAndFlush(student);

    System.out.println("*****************************");
}

结果

*****************************
Hibernate: call next value for student_seq
Hibernate: call next value for student_club_seq
Hibernate: insert into student_club (name, student_id, id) values (?, ?, ?)
Hibernate: insert into student (club, id) values (?, ?)
Hibernate: update student_club set name=?, student_id=? where id=?
*****************************

推荐阅读