列出带有条件的连接表

Cla*_*nei 5 java hibernate jpa 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;
Run Code Online (Sandbox Code Playgroud)

所以我需要做一个标准查询来按产品 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();
Run Code Online (Sandbox Code Playgroud)

但我得到:

java.lang.IllegalArgumentException:验证标准时出错,原因如下:java.lang.IllegalStateException:没有显式选择,无法确定隐式选择

Ern*_*usc 3

这应该有效:

     @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());
     }
Run Code Online (Sandbox Code Playgroud)

请注意,我做了唯一的"one directional"方法。这样做bidirectional,您需要将产品添加到其可行的仓库中(以满足双向条件)。顺便说一句,您的错误丢失了,cq.select(warehouses)这就是为什么您处于非法状态,因为您的查询不知道要选择什么。