JPA之OneToOne示例


3个月前 160次点击 来自 后端

标签: JPA

四个实体类:学生, 教室,老师,课桌

  • 一个学生通常只有一个课桌,一个课桌通常给一个学生作,这里学生和课桌的关系就是互为 @OneToOne
  • 一个教室通常可以容纳很多的学生,教室到学生的关系就可以定义为 @OneToMany
  • 很多学生容纳在一个教室当中,学生到教室的关系可以定义为 @ManyToOne
  • 一个学生可以有很多的老师,一个老师可以有很多的学生,这里学生和老师的关系就互为 @ManyToMany

OneToOne

Student.java

@Entity
@Getter
@Setter
@Table(name = "t_stu")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(length = 100)
    private String name;

    private Integer age;

    /**
     * 定义学生与课桌 一对一
     * JoinTable用于生成中间表 stu_desk 维护学生与课桌的关系 ,如果没有使用JoinTable则会在 stu 表中生成一个指向 desk 的外键 desk_id 用来维护关系
     * CascadeType.PERSIST,CascadeType.MERGE 指定级联保存和级联更新
     */
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(name = "t_stu_desk", joinColumns = @JoinColumn(name = "stu_id"), inverseJoinColumns = @JoinColumn(name = "desk_id"))
    private Desk desk;

    @Transient
    private String test;

}

Desk.java

@Entity
@Getter
@Setter
@Table(name = "t_desk")
public class Desk {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Integer number;

    @OneToOne(mappedBy = "desk")
    private Student student;
}

Test

@Test
void saveStudent() {
    Student student = new Student();
    student.setAge(10);
    student.setName("dailei");
    Desk desk = new Desk();
    desk.setNumber(1);
    student.setDesk(desk);
    studentRepository.save(student);
}

SQL输出:

Hibernate: insert into t_desk (number) values (?)
Hibernate: insert into t_stu (age, name) values (?, ?)
Hibernate: insert into t_stu_desk (desk_id, stu_id) values (?, ?)

Student定义级联关系 CascadeType.PERSIST 指定级联保存必不可少,如果不指定此项 Test 代码将会报错:

object references an unsaved transient instance - save the transient instance before flushing

在未指定级联保存的情况下,消除此错误的解决方式是手动持久化 desk 实例

@Test
void saveStudent() {
    Desk desk = new Desk();
    desk.setNumber(1);
    deskRepository.save(desk);

    Student student = new Student();
    student.setAge(10);
    student.setName("dailei");
    student.setDesk(desk);
    studentRepository.save(student);
}

Made with in Shangrao,China By Devler.

Copyright © Devler 2012 - 2022

赣ICP备19009883号-1

Top ↑