Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > JPQL оператор IN


Автор: drG100k 14.4.2009, 18:57
Здравствуйте!
Нужно смоделировать Прайс-лист с категориями. Категории - дерево. Аннотации и всё лишнее пропущу в коде (чтоб было поменьше)
1 Класс (Entity)
Код

public class Category{
        Long id;
        String name;
        Category parent;
        List<Category> children;
        List<Product> products;
}

2 Класс (Entity)
Код

public class Product{
        Long id;
        String name;
        Category category;
        Double price;
}

И был незамысловатый запрос к базе данных в классе Product
Код

@NamedQuery{name="Select Product from Category", query="SELECT p FROM Product p where p.category = :category"}

И всё бы было хорошо, но!!!
Вздумалось тут поиск производить не в конкретной категории, а во всех вложенных категориях
что я сотворил:
Класс (EJB)
Код

...
List<Category> getChildren(Category c) {} //Ищет прямых детей
...
List<Category> getChildrenFromList(List<Category> list){
   List<Category> res = new ArrayList<Category>();
   for(Category c: list){
         res.addAll(getChildren(c));
  }
    return res;
}
...
List<Category> getAllSubCategories(Category c){
       List<Category> tmp = getChildren(c);
       List<Category> res = new ArrayList<Category>(tmp);
       res.add(c);
       while(!tmp.isEmpty()){
             tmp = getChildrenFromList(tmp);
             res.addAll(tmp);
       }
       return res;
}

 
Теперь хочется сделать запрос
Код

@NamedQuery{name="Select Product from All SubCategories" query="SELECT p FROM Product p where p.category IN (:list) "}

И в качестве аргумента посылать результат getAllSubCategories©, но не хочет JPQL проглатывать такие весчи.
Что бы такое сотворить, чтобы задачка решалась? а может и совсем другим путём пойти, но вот каким?
Спасиба

Автор: SoulKeeper 14.4.2009, 19:49
Ручками через запятую сбивать строки.

Автор: drG100k 14.4.2009, 20:02
Цитата(SoulKeeper @ 14.4.2009,  19:49)
Ручками через запятую сбивать строки.

ага, тоже вариант, а ещё можно послать эти все ORM и сделать всё в старом добром JDBC

Автор: MisterCleric 15.4.2009, 09:14
Здравствуйте всем.
Стоп, ребята, а вот так
Код

SELECT p FROM Product p where p.category.id IN (:list)


и потом так:
Код

 Query q = session.getNamedQuery("Select Product from All SubCategories");
 q.setParameterList("list", ids, Hibernate.LONG);
 p.list();


где ids ИДишники элементов коллекцию по выполнению 
Код



Добавлено через 1 минуту и 20 секунд
Код

List<Category> getAllSubCategories(Category c);

Автор: drG100k 15.4.2009, 10:59
Цитата(MisterCleric @ 15.4.2009,  09:14)
Код
 
q.setParameterList("list", ids, Hibernate.LONG);


Нет такого метода в  интерфейсе javax.persistence.Query

Ещё я тут забыл такую Ооочень (как оказалось) важную деталь PersistentProvider = Toplink

А он требует в качестве параметра к оператору IN Объект класса Category  smile Кто бы мог подумать...
Так что от "ручками созданного" листа тоже толку мало будет
 
НО! Даже если ему скармливаешь Такой объект, он запрос создаёт

Код

SELECT t0.PRODUCT_ID, t0.NAME,  t0.PRICE, t0.CATEGORY FROM PRODUCT t0, CATEGORY t1 WHERE ( IN (?) AND (t1.CATEGORY_ID = t0.CATEGORY))


С другой стороны в доках к EntityManager есть такой вот примерчик

Код

List names = new ArrayList();
names.add("Izi");
names.add("Fritz");
Query q = em.createQuery("select cat from DomesticCat cat where cat.name in (:namesList)");
q.setParameter("namesList", names); 


а ещё в javadoc  java.oracle.toplink.expressions.Expression

Код

Expression    in(boolean[] theBooleans)
          PUBLIC: Return an expression that checks if the receivers value is contained in the collection.
 Expression    in(byte[] theBytes)
          PUBLIC: Return an expression that checks if the receivers value is contained in the collection.
 Expression    in(char[] theChars)
          PUBLIC: Return an expression that checks if the receivers value is contained in the collection.
 Expression    in(double[] theDoubles)
          PUBLIC: Return an expression that checks if the receivers value is contained in the collection.
 Expression    in(Expression arguments)
           
 Expression    in(float[] theFloats)
          PUBLIC: Return an expression that checks if the receivers value is contained in the collection.
 Expression    in(int[] theInts)
          PUBLIC: Return an expression that checks if the receivers value is contained in the collection.
 Expression    in(long[] theLongs)
          PUBLIC: Return an expression that checks if the receivers value is contained in the collection.
 Expression    in(java.lang.Object[] theObjects)
          PUBLIC: Return an expression that checks if the receivers value is contained in the collection.
 Expression    in(ReportQuery subQuery)
           
 Expression    in(short[] theShorts)
          PUBLIC: Return an expression that checks if the receivers value is contained in the collection.
 Expression    in(java.util.Vector theObjects)
          PUBLIC: Return an expression that checks if the receivers value is contained in the collection.



 Тут тебе и Vector, и Object[] 

где-то косяк, а вот где...
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)