JPA加载实体,但在@OneToMany列表中,只加载特定的
JPA load entities, but therein in a @OneToMany list, only load specific
情况:
(使用 Payara 服务器)
我有多个 Group
,每个 Group
都有自己特定的一组 GroupMeeting
。
这些 GroupMeeting
已被跟踪多年。
每个 Group
包含 100-10000 GroupMeeting
s。
但通常只查询和使用当年的GroupMeeting
。
问题:
如何加载所有 Group
s,但只加载每个 Group
的 GroupMeeting
特定时间间隔的列表,例如只加载 GroupMeeting
s 2019?或者,如果需要,具体年份或范围,即 2017-2021 等?
如果我只是 运行 一个 "SELECT *",那么使用 FetchType.LAZY
我会得到一个空的 emtpy List<GroupMeeting>
,但是一旦我在某个地方访问它代码,将加载所有项目。
问题:
什么是最好的策略,即有点有效但又不过分复杂?
- 是否有一个简单的 SQL/JPQL 查询,我可以 运行 使用下面的 类?
- 是否需要进行一些结构上的更改——尤其是注释方面的更改?
- 我应该考虑标准 API 吗?
- 我是否必须使用两个
List<GroupMeeting>
,一个用于常用会议,另一个用于 'old' 会议?
示例:
这里有两个 类:
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,则更容易。
情况: (使用 Payara 服务器)
我有多个 Group
,每个 Group
都有自己特定的一组 GroupMeeting
。
这些 GroupMeeting
已被跟踪多年。
每个 Group
包含 100-10000 GroupMeeting
s。
但通常只查询和使用当年的GroupMeeting
。
问题:
如何加载所有 Group
s,但只加载每个 Group
的 GroupMeeting
特定时间间隔的列表,例如只加载 GroupMeeting
s 2019?或者,如果需要,具体年份或范围,即 2017-2021 等?
如果我只是 运行 一个 "SELECT *",那么使用 FetchType.LAZY
我会得到一个空的 emtpy List<GroupMeeting>
,但是一旦我在某个地方访问它代码,将加载所有项目。
问题: 什么是最好的策略,即有点有效但又不过分复杂?
- 是否有一个简单的 SQL/JPQL 查询,我可以 运行 使用下面的 类?
- 是否需要进行一些结构上的更改——尤其是注释方面的更改?
- 我应该考虑标准 API 吗?
- 我是否必须使用两个
List<GroupMeeting>
,一个用于常用会议,另一个用于 'old' 会议?
示例: 这里有两个 类:
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,则更容易。