如果我有两个班级 - 卡车和设备 - 具有多对多的关系,我希望能够编写JPA CriteriaQuery来查找与某个设备ID匹配的所有卡车。为简单起见,这两个类如下。卡车有设备清单,但设备不知道卡车:
public class Truck {
private Long id;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(
name="truck_equipment",
joinColumns={ @JoinColumn(name="truck_id") },
inverseJoinColumns={ @JoinColumn(name="equip_id") }
)
private List<Equipment> equipment;
}
public class Equipment {
private Long id;
private String equipCode;
}
我知道我可以写一个查询来获取某辆卡车的所有设备,但我喜欢相反:所有带有某些设备的卡车我都无法得到我正在寻找的东西。这是反向查询,它为我提供了某辆卡车的所有设备:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Equipment> cq = cb.createQuery(Equipment.class);
Root<Truck> truckRoot = cq.from(Truck.class);
cq.where(cb.equal(truckRoot.get(Truck_.id), truckId));
ListJoin<Truck, Equipment> trucks = truckRoot.join(Truck_.equipment);
CriteriaQuery<Equipment> cq_e = cq.select(trucks);
TypedQuery<Equipment> query = entityManager.createQuery(cq_e);
query.getResultList();
有人可以帮我解决这个问题的反面吗?
答案 0 :(得分:0)
我们最终做了以下事情。我不确定它是否像其他方式一样高效,但它仍然允许我们保留对我们很重要的元模型类,并将对象引用保留在一边以避免将这些对象写入JSON时的问题(无限递归):
private getEquipmentPredicate(CriteriaBuilder cb, Root<Truck> root) {
EquipmentType type = findEquipmentType("not related to this answer");
Expression<List<EquipmentType>> equipments = root.get(Truck_.equipmentTypes);
Predicate p = cb.isMember(type, equipments);
return p;
}
答案 1 :(得分:0)
我做了诀窍:
String someCode = "xxx";
CriteriaBuilder builder = ...
builder.and(
root.join(Truck_.equipmentTypes).get(Equipment_.equipCode)
.in(Collections.singleton(someCode)
);