有3个实体
组
@Entity
@Table(name = "`group`")
public class Group implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_group")
private Long id;
@OneToMany(mappedBy = "group",cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@OrderColumn(name = "id_student")
private List<Student> students = new ArrayList<>();
@ManyToOne
@JoinColumn(name = "id_faculty")
private Faculty faculty;
.....getters/setters
}
学生
@Entity
@Table(name = "student")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Long.class)
public class Student implements Serializable {
@Id
@Column(name = "id_student")
private Long id;
......
@OneToMany(mappedBy = "student",cascade = CascadeType.ALL,fetch = FetchType.EAGER)
private List<Rating> ratings = new ArrayList<>();
@ManyToOne
@JoinColumn(name = "id_okr")
private OKR okr;
@ManyToOne
@JoinColumn(name = "id_group")
private Group group;
.....getters/setters
}
评分
@Entity
@Table(name = "rating")
public class Rating implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_rating")
private Long id;
@Temporal(TemporalType.DATE)
@Column
private Date date;
@ManyToOne
@JoinColumn(name = "id_student")
private Student student;
@ManyToOne
@JoinColumn(name = "id_paragraph")
private Paragraph paragraph;
.....getters/setters
}
JPA查询
@Query(value = "SELECT g FROM Group g INNER JOIN FETCH g.students s LEFT JOIN FETCH s.ratings r WHERE g.id = :id AND s.group.id = g.id AND (r.student.id = s.id AND r.date BETWEEN :startMonth and :endMonth OR r IS NULL) GROUP BY s.id")
Group findGroupByStudentGroupId(@Param("id") Long id ,@Param("startMonth") Date startMonth, @Param("endMonth") Date endMonth );
我有一个ID为8000的学生,提取查询后,结果列表包含8001个元素,其中包含8个我有的学生和7993个空值。如果删除批注@OrderColumn,则会出现MultiBagException(无法同时获取)。如果将@OrderColumn添加到实体Student中的rating @OneToMany关联中,我的Rating集合和Student集合中的值为空。
对我而言,@OrderColumn的逻辑将空值作为集合中的最大id返回,这似乎很奇怪。有什么办法解决吗?
Hibernate版本5.1.0最终版
Spring Data JPA 1.8.2
最佳答案
当您尝试获取具有特定组和评分的学生时,可以从学生实体获取查询并加入“评分”实体。您不必为组实体显式添加联接,因为它已经与多个学生进行了一对一映射。
您可以按以下方式更改查询:
@Query(value = "SELECT s FROM Student s LEFT JOIN s.ratings r WHERE s.group.id = :id AND (r.date BETWEEN :startMonth and :endMonth OR r IS NULL) GROUP BY s.id")
List<Student> findGroupByStudentGroupId(@Param("id") Long id ,@Param("startMonth") Date startMonth, @Param("endMonth") Date endMonth );