2015-04-13 5 views
2

у меня есть сущность продукта со списком складов с этим частично кодом:Список присоединяемой таблицы с критериями

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; 

Так что мне нужно сделать запрос критерии, чтобы получить список складов по идентификатору продукта.

Я пробовал:

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 java.lang.IllegalStateException: Нет явного выбор и неявный не может быть определен

ответ

2

Это должно работать:

 @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) вот почему вы получили незаконное состояние, потому что ваш запрос не знает, что выбрать.

Смежные вопросы