JPA加载实体,但在@OneToMany列表中,只加载特定的

JPA load entities, but therein in a @OneToMany list, only load specific

情况: (使用 Payara 服务器)

我有多个 Group,每个 Group 都有自己特定的一组 GroupMeeting

这些 GroupMeeting 已被跟踪多年。 每个 Group 包含 100-10000 GroupMeetings。 但通常只查询和使用当年的GroupMeeting

问题:

如何加载所有 Groups,但只加载每个 GroupGroupMeeting 特定时间间隔的列表,例如只加载 GroupMeetings 2019?或者,如果需要,具体年份或范围,即 2017-2021 等?

如果我只是 运行 一个 "SELECT *",那么使用 FetchType.LAZY 我会得到一个空的 emtpy List<GroupMeeting>,但是一旦我在某个地方访问它代码,将加载所有项目。

问题: 什么是最好的策略,即有点有效但又不过分复杂?

示例: 这里有两个 类:

import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;

@Entity
public class Group {
    @Id //
    @GeneratedValue() //
    private long id;

    private String name;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) @JoinTable(name = "group_meetings") //
    private final List<GroupMeeting> meetings = new ArrayList<>();
}

import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class GroupMeeting {
    @Id //
    @GeneratedValue() //
    private long id;

    private String  title;
    private Date    start;
    private Date    end;
}

您可以使用 Hibernate 过滤器来实现,例如:

@Entity
@FilterDef(name="groupMeetingFilter",
        parameters={@ParamDef( name="fromDate", type="date"), @ParamDef(name="toDate", type="date")} )
public class Group {
    @Id //
    @GeneratedValue() //
    private long id;

    private String name;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) @JoinTable(name = "group_meetings")
    @Filter(
        name = "groupMeetingFilter",
        condition="start <= :fromDate and end >= :toDate"
    )
    private final List<GroupMeeting> meetings = new ArrayList<>();
}

并且您需要在应用程序的某处启用过滤器,就像这样:

Session session = HibernateUtil.getSessionFactory().openSession();
Filter filter = session.enableFilter("groupMeetingFilter");
//Define here the dates that you want
filter.setParameter("fromDate", new Date());
filter.setParameter("toDate", new Date());

您可以进一步研究并使过滤器全局可用,例如,如果您使用 Spring,则更容易。