Запрос гибернации для нескольких элементов в коллекции - PullRequest
11 голосов
/ 09 июня 2010

У меня есть модель данных, которая выглядит примерно так:

public class Item {
    private List<ItemAttribute> attributes;
    // other stuff
}

public class ItemAttribute {
    private String name;
    private String value;
}

(это, очевидно, упрощает многие посторонние вещи)

Что я хочу сделать, это создать запросзапрашивать все элементы с одним или более определенными атрибутами, в идеале соединенные с произвольными AND и OR.Прямо сейчас я держу это простым и просто пытаюсь реализовать случай AND.В псевдо-SQL (или псевдо-HQL, если хотите) это будет выглядеть примерно так:

select all items
where attributes contains(ItemAttribute(name="foo1", value="bar1"))
AND attributes contains(ItemAttribute(name="foo2", value="bar2"))

Примеры в документах Hibernate, похоже, не касаются этого конкретного варианта использования, но похоже, чтодовольно распространенный.Случай дизъюнкции также будет полезен, особенно для того, чтобы я мог указать список возможных значений, например

where attributes contains(ItemAttribute(name="foo", value="bar1"))
OR attributes contains(ItemAttribute(name="foo", value="bar2"))
-- etc.

Вот пример, который хорошо работает для одного атрибута:

return getSession().createCriteria(Item.class)
        .createAlias("itemAttributes", "ia")
        .add(Restrictions.conjunction()
            .add(Restrictions.eq("ia.name", "foo"))
            .add(Restrictions.eq("ia.attributeValue", "bar")))
        .list();

Обучениекак это сделать, во многом расширит мое понимание потенциала Hibernate.:)

Ответы [ 5 ]

1 голос
/ 26 июля 2010

Не могли бы вы использовать псевдоним для этого?

Criteria itemCriteria = session.createCriteria(Item.class);
itemCriteria.createAlias("itemAttributes", "ia1")
            .createAlias("itemAttributes", "ia2")
            .add(Restrictions.eq("ia1.name", "foo1"))
            .add(Restrictions.eq("ia1.attributeValue", "bar1")))
            .add(Restrictions.eq("ia2.name", "foo2"))
            .add(Restrictions.eq("ia2.attributeValue", "bar2")))

Не уверен, как hibernate обрабатывает объединение с одним и тем же свойством в два раза явно, может быть, стоит попробовать?

0 голосов
/ 15 апреля 2013

Используйте LEFT_OUTER_JOIN для предотвращения проблемы типа "WHERE x = 1 AND x = 2"

CreateAlias ​​("itemAttributes", "ia", JoinType.LEFT_OUTER_JOIN)

0 голосов
/ 11 июня 2010

Почему бы не работать следующее?

return getSession().createCriteria(Item.class)
    .createAlias("itemAttributes", "ia")
    .add(Restrictions.or()
        .add(Restrictions.conjunction()
            .add(Restrictions.eq("ia.name", "foo1"))
            .add(Restrictions.eq("ia.attributeValue", "bar1")))
        .add(Restrictions.conjunction()
            .add(Restrictions.eq("ia.name", "foo2"))
            .add(Restrictions.eq("ia.attributeValue", "bar2"))))
    .list();

Это было бы (name=foo1 && attributeValue=bar1) OR (name=foo2 && attributeValue=bar2)

0 голосов
/ 15 июля 2010

Я не проверял это, но я должен попытаться решить вашу проблему, если мне придется:

Map<String,String> map1 = new TreeMap<String,String>();  
map1.put("ia.name","foo1");  
map1.put("ia.value","bar1");  
Map<String,String> map2 = new TreeMap<String,String>();  
map2.put("ia.name","foo2");  
map2.put("ia.value","bar2");  
return getSession().createCriteria(Item.class)
.createAlias("itemAttributes", "ia")
.add(Restrictions.and()
     .add(Restrictions.allEq(map1))
     .add(Restrictions.allEq(map2))
)
.list();

Пожалуйста, дайте мне знать, если это сработало. Я думаю, что то же самое должно работать с или () ...

0 голосов
/ 09 июня 2010
SELECT item FROM Item item JOIN item.attributes attr 
    WHERE attr IN (:attrList) GROUP BY item

и затем в коде Java:

List<ItemAttribute> attrList = new ArrayList<ItemAttribute>();
attrList.add(..); // add as many attributes as needed
...// create a Query with the above string
query.setParameter("attrList", attrList);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...