使用@OrderColumn的JPA多重获取返回多个null值

时间:2019-03-19 11:28:58

标签: java hibernate jpa spring-data-jpa hibernate-mapping

有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返回,这似乎很奇怪。有什么办法解决吗?
休眠版本5.1.0最终版
Spring Data JPA 1.8.2

1 个答案:

答案 0 :(得分:0)

在尝试获取具有特定组和评分的学生时,可以从学生实体获取查询,并加入“评分”实体。您不必显式为组实体添加连接,因为它已经与多个学生进行了一个映射。

您可以按以下方式更改查询:

@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 );