如何使用元模型选择具有条件查询的父项引用的引用子实体

时间:2018-01-19 15:50:39

标签: jpa eclipselink criteria-api

我正在使用带有元模型的jpa条件查询API搜索选择父实体的所有子元素的方法。

表格家庭

@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}

}

表格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;}
}

现在我想选择家庭的所有子实体,就在选择家庭时,而不是使用更慢的方法来获取所有家庭的列表,循环遍历列表并填充家庭成员列表。

为了用纯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()时,我得到一个仅包含族实体的列表,其中族表行的长度乘以family_memebers的行。

1 个答案:

答案 0 :(得分:0)

重新解释你的问题:你想要的是一个家庭实体列表,以及急切提取的Family.familyMembers,对吧?在这种情况下,您需要fromFamily.fetch(...)而不是fromFamily.join(...)