2011-02-17 2 views
0

У меня есть модель данных Hibernate/JPA, которая позволяет размещать объекты (MyObj) в различных категориях (MyCategory). Каждая категория может иметь 0 или более подкатегорий, а категории, которые вместо этого не имеют классификации (MyClassification), назначенной им. Модель данных выглядит следующим образом:Проблема с Hibernate/JPA. Запрос и категории

public class MyObj { 

    … 

    protected MyCategory category = null; 

    … 
} 

public class MyCategory { 

    … 

    protected MyClassification classification=null; 

    protected List<MyCategory> childCategories=null; 

    protected MyCategory parentCategory=null; 

    … 

} 

public class MyClassification { 

    … 

} 

я хотел бы, чтобы иметь возможность запрашивать экземпляры MyObj на основе классификации, категории или подкатегории. Например, если у меня есть 3 классификации (класс А, класс В и класс С) и 6 категорий (например, категория А1, категория А2, категория В1 и т. Д., Где название соответствует классификации), и каждая из этих категорий имеет 3 подкатегории (например, subcatA1, subcatA2, subcatA3, subcatB1 и т.д.) Я хотел бы сделать запросы как это:

  • Все MyObj экземпляры в классификации CLASSA (независимо от категории или подкатегории)
  • Все MyObj экземпляры в категории categoryA1 (независимо от того, подкатегории)

Я создал пару NamedQueries, которые, как я думал, достигнут этого. Они отлично работают в случаях, когда экземпляр MyObj был назначен подкатегории. Однако, если я помещаю экземпляр MyObj в категорию (без подкатегории) и запрос на основе класса, я не вижу его. Я вижу только экземпляры MyObj, которые находятся внутри подкатегории. Мои запросы выглядят так:

MyObj.findByClass = "SELECT DISTINCT o FROM MyObj o WHERE (o.category.classification = :classification OR o.category.parentCategory.classification = :classification)" 

MyObj.findByCategory = "SELECT DISTINCT o FROM MyObj o WHERE (o.category = :category OR o.category.parentCategory = :category)" 

Может ли кто-нибудь сказать мне, где ошибка в моей логике для этих запросов? Есть ли лучший способ добиться того, что мне нужно?

ответ

2

проблема с запросом, что o.category.parentCategory записывается как inner join category cat on cat.id=o.parent_category, и если parentCategory является NULL вы не получите никакого результата.

Таким образом, точка-навигация подразумевает внутренние соединения, которые вызывают проблемы с операторами OR. Вы должны использовать явные запросы LEFT JOINs или UNION.

На Замечание, QueryDSL позволяет писать такие заявления:

from(QCategory.category) 
.where(QCategory.category.classification.eq(classification).or(QCategory.category.left().parentCategory().left().classification.eq(classification)) 
.listDisticnt(QCategory.category) 

SELECT DISTINCT FROM MyObj O о где (= o.category.classification: классификация OR = o.category.parentCategory.classification: классификация) «

0

Я думаю, что вам не хватает в «классификации» в первом запросе, после OR:

MyObj.findByClass = "SELECT DISTINCT o FROM MyObj o WHERE (o.category.classification = :classification OR o.category.parentCategory.classification = :classification)" 

На стороне записки, мне кажется, что обход графа объекта является более простым, чем выдача HQL запросов

+0

Исправлено недостающее поле в запросе. – Shadowman

+1

прав, SQL (или HQL) не может искать в деревьях простым способом ... Вы можете искать все категории с нужной классификацией и использовать вторую HQL для поиска всех Obj с любой из найденных вами категорий. –

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