【发布时间】:2021-01-06 11:44:51
【问题描述】:
使用 Java 11、Spring Boot 和 Spring Data JPA
概述
我想使用 Spring Data JPA 访问 mysql 数据库中的 3 个连接表。为简单起见,我们称它们为 student、course 和 performance_report。
这是我的数据类:
@Entity
@Table(name = "student")
@Data
public class Student {
@Id
@Column(name = "student_id")
private Long studentId;
@Column(name = "student_name")
private String studentName;
@OneToMany(mappedBy = "student", fetch = FetchType.EAGER,
cascade = CascadeType.ALL)
private List<PerformanceReport> performanceReports;
}
@Entity
@Table(name = "course")
@Data
public class Course {
@Id
@Column(name = "course_id")
private Long courseId;
@Column(name = "course_name")
private String courseName;
}
@Entity
@Table(name = "performance_report")
@Data
public class PerformanceReport {
@Id
@Column(name = "performance_report_id")
private Long performanceReportId;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "student_id", nullable = false)
// JsonBackReference needed to prevent infinite recursion.
@JsonBackReference
private Student student;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "course_id", nullable = false)
private Course course;
@Column(name = "grade")
private String grade;
@Column(name = "attendance")
private String attendance;
}
这是我的 StudentRepository:
public interface StudentRepository extends JpaRepository<Student, Long> {
Optional<Student> findById(Long studentId);
}
调用 StudentRepository.findById 会产生一个像这样的对象:
{
"studentId": 1,
"studentName": "Spongebob Squarepants",
"performanceReports": [
{
"performanceReportId": 5473,
"course": {
"courseId": 643,
"courseName": "Boating 101"
},
"grade": "F",
"attendance": "100%"
},
{
"performanceReportId": 4723,
"course": {
"courseId": 346,
"courseName": "Grilling 101"
},
"grade": "A+",
"attendance": "100%"
}
]
}
问题
我还想执行此操作的逆操作,以便查询 Course 并获取如下对象:
{
"courseId": 346,
"courseName": "Grilling 101",
"performanceReports": [
{
"performanceReportId": 4723,
"student": {
"studentId": 1,
"studentName": "Spongebob Squarepants"
},
"grade": "A+",
"attendance": "100%"
},
{
"performanceReportId": 4774,
"student": {
"studentId": 4,
"studentName": "Squidward Tentacles"
},
"grade": "C-",
"attendance": "72%"
}
]
}
我目前的实体结构无法做到这一点。
如果我以与 Student 相同的方式为 Course 设置连接 - 通过在 Course 中添加 @OneToMany 并在 @987654333 中的第二个 @ManyToOne 中添加 @JsonBackReference @ - 我的结果中不会有任何 Student 数据。它还将阻止Course 数据流向Student 查询。如果我删除 @JsonBackReference 注释,我会得到无限递归和 StackOverflow 错误。
我尝试创建单独的实体来解决这些情况。我从Student 中删除了连接,并将其放在扩展Student 的类中。然后我对Course 和PerformanceReport 做同样的事情。这不仅会导致新的错误,而且非常混乱。它还要求我创建单独的存储库来处理这些扩展类。
一定有更好的办法。
我的处理方法正确吗? Spring Data JPA 是完成此类任务的最佳方式吗?如果我想在不使用任何连接的情况下查询Student 或Course 怎么办?
当然,我并不需要针对每种可能的情况都使用新实体。如何自定义连接不同查询的表的方式?
【问题讨论】:
标签: java json serialization spring-data-jpa circular-reference