列出符合条件的加入 table
List a Joined table with criteria
我有一个
带有部分代码的仓库列表的产品实体:
Product.java
@ManyToMany
@JoinTable(name = "product_has_warehouse", joinColumns = @JoinColumn(name = ID), inverseJoinColumns = @JoinColumn(
name = "warehouse_id"), foreignKey = @ForeignKey(name = FK + "has_warehouse"),
inverseForeignKey = @ForeignKey(name = FK + "warehouse"))
private List<Warehouse> warehouses;
所以我需要进行条件查询以按产品 ID 获取仓库列表。
我试过:
final CriteriaQuery<Warehouse> query = getCriteriaBuilder().createQuery(Warehouse.class);
final Root<Product> root = query.from(Product.class);
final Join<Product, Warehouse> warehouseJoin = root.join("warehouses");
query.where(getCriteriaBuilder().in(warehouseJoin));
final TypedQuery<Warehouse> typedQuery = getEm().createQuery(query);
return typedQuery.getResultList();
但我得到:
java.lang.IllegalArgumentException: Error occurred validating the
Criteria Caused by: java.lang.IllegalStateException: No explicit
selection and an implicit one could not be determined
这应该有效:
@Test
public void getWarehousesByProduct() {
Product drinks = new Product("drinks");
Warehouse wh1 = new Warehouse("house1");
Warehouse wh2 = new Warehouse("house2");
Warehouse wh3 = new Warehouse("house3");
Warehouse wh4 = new Warehouse("house4");
Warehouse wh5 = new Warehouse("house5");
Warehouse wh6 = new Warehouse("house6");
drinks.getWarehouses().add(wh1);
drinks.getWarehouses().add(wh2);
drinks.getWarehouses().add(wh3);
drinks.getWarehouses().add(wh4);
saveAll(Arrays.asList(new Warehouse[]{wh1,wh2,wh3,wh4,wh5,wh6}));
em.persist(drinks);
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Warehouse> cq = cb.createQuery(Warehouse.class);
Root<Product> product = cq.from(Product.class);
Join<Product, Warehouse> warehouses = product.join("warehouses");
cq.select(warehouses).where(cb.equal(product.get("id"), drinks.getId()));
TypedQuery<Warehouse> tq = em.createQuery(cq);
List<Warehouse> result = tq.getResultList();
Assert.assertNotNull(result);
Assert.assertEquals(drinks.getWarehouses().size(), result.size());
}
注意我只做了 "one directional"
方式。做 bidirectional
方式,你需要将产品添加到它的可行仓库(以满足双向条件)。
顺便说一句,你的错误是遗漏了 cq.select(warehouses)
这就是你得到非法状态的原因,因为你的查询不知道要 select.
我有一个 带有部分代码的仓库列表的产品实体:
Product.java
@ManyToMany
@JoinTable(name = "product_has_warehouse", joinColumns = @JoinColumn(name = ID), inverseJoinColumns = @JoinColumn(
name = "warehouse_id"), foreignKey = @ForeignKey(name = FK + "has_warehouse"),
inverseForeignKey = @ForeignKey(name = FK + "warehouse"))
private List<Warehouse> warehouses;
所以我需要进行条件查询以按产品 ID 获取仓库列表。
我试过:
final CriteriaQuery<Warehouse> query = getCriteriaBuilder().createQuery(Warehouse.class);
final Root<Product> root = query.from(Product.class);
final Join<Product, Warehouse> warehouseJoin = root.join("warehouses");
query.where(getCriteriaBuilder().in(warehouseJoin));
final TypedQuery<Warehouse> typedQuery = getEm().createQuery(query);
return typedQuery.getResultList();
但我得到:
java.lang.IllegalArgumentException: Error occurred validating the Criteria Caused by: java.lang.IllegalStateException: No explicit selection and an implicit one could not be determined
这应该有效:
@Test
public void getWarehousesByProduct() {
Product drinks = new Product("drinks");
Warehouse wh1 = new Warehouse("house1");
Warehouse wh2 = new Warehouse("house2");
Warehouse wh3 = new Warehouse("house3");
Warehouse wh4 = new Warehouse("house4");
Warehouse wh5 = new Warehouse("house5");
Warehouse wh6 = new Warehouse("house6");
drinks.getWarehouses().add(wh1);
drinks.getWarehouses().add(wh2);
drinks.getWarehouses().add(wh3);
drinks.getWarehouses().add(wh4);
saveAll(Arrays.asList(new Warehouse[]{wh1,wh2,wh3,wh4,wh5,wh6}));
em.persist(drinks);
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Warehouse> cq = cb.createQuery(Warehouse.class);
Root<Product> product = cq.from(Product.class);
Join<Product, Warehouse> warehouses = product.join("warehouses");
cq.select(warehouses).where(cb.equal(product.get("id"), drinks.getId()));
TypedQuery<Warehouse> tq = em.createQuery(cq);
List<Warehouse> result = tq.getResultList();
Assert.assertNotNull(result);
Assert.assertEquals(drinks.getWarehouses().size(), result.size());
}
注意我只做了 "one directional"
方式。做 bidirectional
方式,你需要将产品添加到它的可行仓库(以满足双向条件)。
顺便说一句,你的错误是遗漏了 cq.select(warehouses)
这就是你得到非法状态的原因,因为你的查询不知道要 select.