【问题标题】:Many to one relationship with a condition与条件的多对一关系
【发布时间】:2022-01-11 10:53:09
【问题描述】:

我有两张表,student 和 teacher,关系为 ManyToOne。表结构如下

student(
    id long,
    student_id string,
    ....
    teacher_id string,
    active boolean
)

teacher(
    id long,
    teacher_id string,
    ....
    active boolean
)

我正在使用 Spring Boot 和 Hibernate。此处更新实体时,表中现有行的活动列将设置为 false,并且将添加一个新行,并使用新的 id(long) 和活动为 true。这就是为什么每个表中有两个 id 值。这里的问题是我已经在我的实体中指定了学生与教师的关系,外键为teacher_id。

@Entity
@Table(name = "student")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "student_id")
    private String studentId;

    @ManyToOne
    @JoinColumn(name = "teacher_id", referencedColumnName = "teacher_id")
    private Teacher teacher;

    @Column(name = "active")
    @JsonIgnore
    private Boolean active = true;
}

@Entity
@Table(name = "teacher")
public class Teacher {

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

    @Column(name = "teacher_id")
    private String teacherId;

    @OneToMany(mappedBy = "teacher")
    private Set<Student> students = new HashSet<>();

    @Column(name = "active")
    @JsonIgnore
    private Boolean active = true;
}

但是由于可以使用相同的teacher_id 出现多个教师,因此失败了。有没有办法给关系提供条件以获取 active 为 true 的老师?在表中,将只有一位具有给定 id 且 active 为 true 的教师。

【问题讨论】:

  • 您可能还应该包含Teacher 的实体类。
  • 添加了教师实体@TimBiegeleisen
  • “多个教师可以使用相同的teacher_id”->这应该是不可能的。它违背了 id 的全部目的。
  • Teacher实体的主键是id,不是teacher_id。当实体更新时,id 会改变。并且学生实体映射到teacher_id而不是id。
  • @Nipun 这没有任何意义,因为那个“id”有/可以是重复的,你永远不会知道你的学生实际映射到哪个老师

标签: java spring-boot hibernate many-to-one


【解决方案1】:

Teacher 实体中不应有 teacher_id 外键字段。相反,只需使用主键 id 列。考虑这个版本的实体:

@Entity
@Table(name = "student")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "student_id")
    private String studentId;

    @ManyToOne
    @JoinColumn(name = "teacher_id", referencedColumnName = "id")
    private Teacher teacher;

    @Column(name = "active")
    @JsonIgnore
    private Boolean active = true;
}

@Entity
@Table(name = "teacher")
public class Teacher {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "teacher")
    private Set<Student> students = new HashSet<>();

    @Column(name = "active")
    @JsonIgnore
    private Boolean active = true;
}

这种设计应该强制一个给定的学生只能与一个老师相关联(尽管一个给定的老师可以有多个学生)。

【讨论】:

  • 是的,这会起作用,但这里的问题是,每当我更新教师实体时,都会生成一个带有新 ID 的新行(客户要求)。因此,如果我正在映射 id,我还需要注意更新学生实体中的映射 id,对吗?
  • 不,不是。假设你找了一位老师,然后创建一个新的Student。只要你分配学生和老师的关系,当你save()JPA/Hibernate 应该为你处理剩下的事情。
  • 考虑这种情况,我创建了一个教师 -> 创建了一个映射到该教师的学生 -> 更新教师,而不是学生。这不会改变学生的映射ID,对吧?
  • 我已经回答了您最初的问题,据我估计,该问题以实体定义为中心。如果您需要有关某些 JPA 工作流程的帮助,您应该编辑您的问题并揭示该问题,或者提出一个新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-20
  • 2017-08-07
  • 1970-01-01
  • 1970-01-01
  • 2018-03-16
  • 1970-01-01
  • 2021-05-25
相关资源
最近更新 更多