Seam EntityQuery Соединения «многие ко многим», «Разное» и «Oracle» - PullRequest
0 голосов
/ 21 июля 2011

Я новичок в Seam в уже созданном проекте, поэтому большой объем кода, который я использую, заимствован, и я не всегда полностью уверен, как все работает. Моя проблема заключается в том, что я использую объект запроса, расширенный от EntityQuery, для создания резервной копии страницы списка с возможностями поиска и сортировки, которая должна выполнять поиск по взаимосвязи «многие ко многим» и отдельным отношениям «многие к одному», которые также должны использоваться для Сортировать. Поскольку отношение «многие ко многим» необходимо объединить, чтобы обеспечить возможность поиска, запрос возвращает дубликаты записей для каждого назначения. Это не имеет большого значения, потому что я просто добавил «разные» в ejbql, и это сработало нормально. Тем не менее, когда я пытаюсь упорядочить по другим отношениям многие-к-одному, Oracle выдает ошибку. Похоже, что Oracle не примет заказ по столбцу, которого нет в предложении select, при использовании отдельного ключевого слова http://ora -01791.ora-code.com / и http://oraclequirks.blogspot.com/2009/04/ora-01791-not-selected-expression.html.

Вот отношения, как они определены в объектах: [Subject m: m JobFunction] (очевидно, через таблицу назначений [Subject o: m Subject_JobFunction m: o JobFunction]) и [Subject m: o Type]. Поскольку мне нужно искать Subject по JobFunction, он включается в ejbql, который требует, чтобы отличное ключевое слово возвращало только отдельные Subjects на страницу списка. Когда я пытаюсь упорядочить по Type.name (через отношение многие-к-одному), результирующий запрос раздражает Oracle и выдает ошибку «ORA-01791: not SELECTed expression». Код темы запроса:

@Override
public String getEjbql() {
    return "select subject from Subject subject left outer join subject.jobFunctions as jobFunction";
}

@Override
@SuppressWarnings("rawtypes")
public List<ValueExpression> getRestrictions() {
    ValueExpression[] RESTRICTIONS = { 
            createValueExpression("lower(subject.name) like #{subjectQuery.prepRestriction(subjectQuery.subject.name)}"), 
            createValueExpression("subject.active = #{subjectQuery.active}"), 
            createValueExpression("subject.type.name = #{subjectQuery.typeName}"), 
            createValueExpression("jobFunction.name = #{subjectQuery.jobFunctionName}")
            };
    return Arrays.asList(RESTRICTIONS);

}

Когда я устанавливаю порядок запросов, когда пользователь сортирует по имени типа через интерфейс:

"#{subjectQuery.order=='UPPER(subject.type.name) asc'}"

Я получаю ошибку Oracle. Если я возьму отличительные от ejbql, сортировка работает нормально, но я получаю дубликаты записей Subject. Когда я добавляю отдельное ключевое слово, список работает нормально без дублирующихся записей, но сортировка выдает ошибку. Есть ли у кого-нибудь предложения о том, как я могу реструктурировать ejbql, чтобы он возвращал отдельные записи без отдельного ключевого слова, чтобы сделать сортировку счастливой, или как сделать сортировку, не раздражая Oracle, что столбец сортировки, на который есть ссылка в запросе, отсутствует в предложении select ? Я прочитал несколько мест, где мой ответ может быть в Hibernate Criteria API, но я не знаю, как использовать его в контексте расширенного класса EntityQuery с тем, что я пытаюсь достичь. Пожалуйста, помогите!

Ответы [ 2 ]

0 голосов
/ 21 июля 2011

Я не уверен, насколько сгенерированный запрос (ы) отличается (но), но я нашел ответ.Я не знал о команде fetch для hibernate, которая исправляет необходимость в отдельном ключевом слове (опять же, точно не знаю, каким образом, возможно, путем подзапроса?).После изменения ejbql на:

@Override
public String getEjbql() {
    return "select subject from Subject subject left join fetch subject.jobFunctions jobFunction";
}

отчет больше не нужен, и поэтому Oracle не жалуется на то, что порядок по столбцу отсутствует в предложении select.Список работает, как и ожидалось, и столбец сортировки работает!Yay!

Как и ожидалось, я нашел ответ здесь на stackoverflow.Вопрос был не совсем таким, но синтаксис hql работал для меня: порядок HQL внутри коллекции

0 голосов
/ 21 июля 2011

Если вы добавляете DISTINCT, значит, что-то не работает.

"Поскольку отношение« многие ко многим »необходимо объединить, чтобы обеспечить возможность поиска, запрос возвращает повторяющиеся записи для каждого назначения. "

Рассмотрим случай, когда человек может работать над многими проектами, а в проекте может быть много людей.Существует уникальность «человек / проект».Если вам нужен список людей, которые работают в проекте A или B (или в обоих), тогда вы можете получить

FRED/PROJ_A
BILL/PROJ_A
FRED/PROJ_B
TOM/PROJ_B
BILL/PROJ_C

Если вы показываете только имена (не проекты), вы все равно можете заказать по проекту, но вы увидите

FRED
BILL
FRED
TOM
BILL

Если вы делаете DISTINCT, вы больше не можете делать заказы по проектам, потому что вы не знаете, является ли FRED из PROJ_A или PROJ_B, или BILL приходит перед TOM(на основе PROJ_A) или после TOM (на основе PROJ_C).

Поэтому удалите DISTINCT и всегда показывайте столбец, по которому вы заказываете (потому что тогда вы поймете, почему дубликаты на самом деле не дублируются).

...