我有两个具有一对多关系的实体对象(A和B)。我正在使用JPA(Hibernate)来连接这些表并查询它们以获取特定的结果集,但是在获取结果时我没有应用为子表(B)指定的条件。这就是我定义查询的方式:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<A> query = builder.createQuery(A.class);
Root<A> a = query.from(A.class);
Join<A, B> abJoined = a.join(A_.b);
query.distinct(true)
.where(builder.and(
builder.equal(a.get(A_.id), id),
builder.equal(a.get(A_.active), 1),
builder.equal(a.get(A_.location), 1011),
builder.equal(a.get(A_.status), "Pending"),
builder.equal(abJoined.get(B_.status), "Not Moved"),
builder.greaterThan(abJoined.get(B_.detailId), 0)
));
当我致电entityManager.createQuery(query).getResultList();
时,我得到一个实体'A'的实例,但是当我尝试通过'A'a.getB()
访问'B'时,我为{{1}指定了两个标准没有应用,我得到'B'加入'A'的所有实例。为了达到这些标准,我还需要做些什么吗?如果无法应用标准,是否有推荐的方法从结果集中删除“B”的相应实例?
如有必要,我可以提供更多代码或其他详细信息。
答案 0 :(得分:0)
该查询用于选择查询必须返回哪些A实体。但是A实体永远不会是仅包含其Bs子集的部分实体。它们将始终是A的完整实例,反映A在数据库中的状态,以及A与哪个B相关。
顺便说一下,即使这是可能的(它不是,并且明显禁止JPA规范),你的查询至少也必须使用获取连接来加载Bs。否则,查询只返回A的状态,并且链接的Bs被懒惰地加载。答案 1 :(得分:0)
但在JPA中,对于@OneToMany关系,Query首先在master上触发,所有Criteria和fetches只是主记录。 稍后单独地查询被触发,但是但是...... B表标准将不包含所有条件,而是仅包含一个条件,即仅获取主记录的主键VALUE,即只有一个条件“b。 A_id = [主要从主人那里获取]“
解决方案很简单 创建一个独立的类,我们需要@OneToMany关系字段
第1步
public class AB {
private A a;
private B b; //@OneToMany with A in the Entity class definitions
public AB(){}
public AB(A a, B b){ ///Very Important to have this constructor
this.a=a;
this.b=b;
}
getter setter....
}
第2步
CriteriaQuery<AB> q = criteriaBuilder.createQuery(AB.class);
Root<A> fromA = criteriaQuery.from(A.class);
List<Predicate> predicates = new ArrayList<Predicate>();
Join<A,B> fromB = fromA.join("b", JoinType.INNER);/*"b",fieldName of B in entity Class A*/
criteriaQuery.select(criteriaBuilder.construct(AB.class,A,B));//looks AB's 2 param constr.
predicates.add(criteriaBuilder.equal(fromA.get("name"), filter.getName()));
predicates.add(criteriaBuilder.equal(fromB.get("salary"), filter.getSalary()));
..........
List<AB> ABDataList = typedQuery.getResultList();
for(AB eachABData :ABDataList){
....put in ur objects
obj.setXXX(eachABData.getA().getXXX());
obj.setYYY(eachABData.getB().getYYY());
}
这将给出应用所有条件的所有结果到主表A,并比较表B的主键而不是外键。