如何 select 引用父实体引用的子实体,使用元模型进行标准查询
How to select referenced children entity referenced by a parent with criteria query using metamodel
我正在寻找一种方法 select 使用带有元模型的 jpa 条件查询 API 父实体的所有子实体。
Table 家庭
@Entity
@Table(name = "FAMILIES")
public class Family {
private Long familyId;
private String familyName;
private List<FamilyMember> familyMembers;
@Id
@Column(name="ID_FAMILY")
@GeneratedValue(strategy = Generator.AUTO)
public Long getFamilyId() { return familyId;}
public void setFamilyId(Long fId) { familyId = fId;}
@Column(name = "family_name")
public String getFamilyName() { return familyName;}
public void setFamilyName(String fN) { familyName = fN;}
@OneToMany(mappedBy = "family")
@JoinColumn(name = "id_family")
public List<FamilyMember> getFamilyMembers() { return familyMembers;}
public void setFamilyMembers(List<FamilyMember> fM) { familyMembers = fM}
}
Table family_members
@Entity
@Table(name = "family_members")
public class FamilyMember {
private Long familyMemberId;
private Family family;
private String name;
private String role;
@Id
@Column(name="ID_FAMILY_MEMBER")
@GeneratedValue(strategy = Generator.AUTO)
public Long getFamilyMemberId() { return familyMemberId;}
public void setFamilyMemberId(Long fMId) { familyMemberId = fMId;}
@ManyToOne
@JoinColumn(name = "id_family")
public String getFamily() { return family;}
public void setFamily(Family f) { family = f;}
@Column(name = "name")
public String getFamilyMemberName() { return name;}
public void setFamilyMemberName(String fMN) { name = fMN;}
@Column(name = "role")
public String getFamilyMemberRole() { return role;}
public void setFamilyMemberRole(String fMR) { role = fMR;}
}
现在我想 select 家庭的所有子实体,就在 selecting 家庭时,而不是使用更慢的方法来获取所有家庭的列表,遍历列表并填写家庭成员列表。
为了实现这个结果 qith plain SQL,我写了一个这样的查询:
SELECT f.family_name, fM.name, fM.role FROM families AS f LEFT JOIN family_members AS fM ON fM.id_family = f.id_family;
现在我的问题是,如何将此本机查询转换为标准 API 查询。
实际上根据标准 API 我试过这个:
// Init of EntityManager (eM)
CriteriaBuilder cB = eM.getCriteriaBuilder();
CriteriaQuery<Family> fCQ = cB.createQuery(Family.class);
Root<Family> fromFamily = fCQ.from(Family.class);
// My actual implementation
ListJoin<Family, FamilyMember> members = fromFamily.join(Family_.familyMembers);
TypedQuery<Family> fTQ = eM.createQuery(fCQ);
但是当我调用 getResultList() 时,我得到一个仅包含家庭实体的列表,家庭行的长度 table 乘以 family_memebers 的行数。
重新表述您的问题:您想要的是 Family 实体的列表,以及急切获取的 Family.familyMembers
,对吗?在这种情况下,您需要 fromFamily.fetch(...)
而不是 fromFamily.join(...)
。
我正在寻找一种方法 select 使用带有元模型的 jpa 条件查询 API 父实体的所有子实体。
Table 家庭
@Entity
@Table(name = "FAMILIES")
public class Family {
private Long familyId;
private String familyName;
private List<FamilyMember> familyMembers;
@Id
@Column(name="ID_FAMILY")
@GeneratedValue(strategy = Generator.AUTO)
public Long getFamilyId() { return familyId;}
public void setFamilyId(Long fId) { familyId = fId;}
@Column(name = "family_name")
public String getFamilyName() { return familyName;}
public void setFamilyName(String fN) { familyName = fN;}
@OneToMany(mappedBy = "family")
@JoinColumn(name = "id_family")
public List<FamilyMember> getFamilyMembers() { return familyMembers;}
public void setFamilyMembers(List<FamilyMember> fM) { familyMembers = fM}
}
Table family_members
@Entity
@Table(name = "family_members")
public class FamilyMember {
private Long familyMemberId;
private Family family;
private String name;
private String role;
@Id
@Column(name="ID_FAMILY_MEMBER")
@GeneratedValue(strategy = Generator.AUTO)
public Long getFamilyMemberId() { return familyMemberId;}
public void setFamilyMemberId(Long fMId) { familyMemberId = fMId;}
@ManyToOne
@JoinColumn(name = "id_family")
public String getFamily() { return family;}
public void setFamily(Family f) { family = f;}
@Column(name = "name")
public String getFamilyMemberName() { return name;}
public void setFamilyMemberName(String fMN) { name = fMN;}
@Column(name = "role")
public String getFamilyMemberRole() { return role;}
public void setFamilyMemberRole(String fMR) { role = fMR;}
}
现在我想 select 家庭的所有子实体,就在 selecting 家庭时,而不是使用更慢的方法来获取所有家庭的列表,遍历列表并填写家庭成员列表。
为了实现这个结果 qith plain SQL,我写了一个这样的查询:
SELECT f.family_name, fM.name, fM.role FROM families AS f LEFT JOIN family_members AS fM ON fM.id_family = f.id_family;
现在我的问题是,如何将此本机查询转换为标准 API 查询。
实际上根据标准 API 我试过这个:
// Init of EntityManager (eM)
CriteriaBuilder cB = eM.getCriteriaBuilder();
CriteriaQuery<Family> fCQ = cB.createQuery(Family.class);
Root<Family> fromFamily = fCQ.from(Family.class);
// My actual implementation
ListJoin<Family, FamilyMember> members = fromFamily.join(Family_.familyMembers);
TypedQuery<Family> fTQ = eM.createQuery(fCQ);
但是当我调用 getResultList() 时,我得到一个仅包含家庭实体的列表,家庭行的长度 table 乘以 family_memebers 的行数。
重新表述您的问题:您想要的是 Family 实体的列表,以及急切获取的 Family.familyMembers
,对吗?在这种情况下,您需要 fromFamily.fetch(...)
而不是 fromFamily.join(...)
。