Как в Seam создать ограничение/псевдоним подзапроса HQL?

Я все еще новичок в Seam/Hibernate, и мне трудно найти решение этой проблемы. Существует сложная взаимосвязь, которую мне нужно искать, и одна из проблем заключается в том, что это должен быть «подобный» поиск для объединения двух столбцов в двух разных сопоставленных объектах. Список результатов представляет собой список сущностей PurchaseOrder, а вот отношения сопоставления: PurchaseOrder [ 1 -- 0..* ] LineItem [ 1 -- 0..* ] BillingCode [ 1 -- 1 ] Project [ 1..* - - 1 ] Компания.

По сути, «BillingCode» представлен «Company.companyCode || '-' || Project.projectCode», так что пользователь видит представленный код биллинга, и именно так он будет пытаться искать заказы на покупку, которые имеют по крайней мере один платежный код, такой как строка поиска, которую они вводят в интерфейсе. Я думаю, что у меня все в порядке, если я выполняю поиск равных, но клиент хотел бы иметь возможность возвращать что-либо с определенной строкой в ​​репрезентативном коде выставления счетов. Вот где это становится сложно.

Я думаю, что было бы нормально, если бы я мог использовать псевдоним для подзапроса и ссылаться на этот псевдоним, но я знаю о ошибка, которая не исправлена в используемой нами версии Seam/Hibernate. В настоящее время я использую реализацию EntityQuery, но изучаю API критериев.

this.setEjbql("select purchaseOrder from PurchaseOrder as purchaseOrder left join fetch purchaseOrder.vendor");

@SuppressWarnings("rawtypes")
ValueExpression[] restrictionsArray = { 
    createValueExpression("purchaseOrder.purchaseOrderNumber = #{purchaseOrderQuery.prepRestriction(purchaseOrder.purchaseOrderNumber)}"), 
    createValueExpression("lower(concat(purchaseOrder.submitterEff.user.firstName, purchaseOrder.submitterEff.user.lastName)) like #{purchaseOrderQuery.preppedSubmitterName}"),
    createValueExpression("lower(purchaseOrder.vendor.name) like #{purchaseOrderQuery.prepRestriction(purchaseOrderQuery.vendorName)}"),
    createValueExpression("lower(concat(purchaseOrder.requestor.user.firstName, purchaseOrder.requestor.user.lastName)) like #{purchaseOrderQuery.preppedRequestorName}"),
    createValueExpression("purchaseOrder.status = #{purchaseOrder.status}"),
    createValueExpression("purchaseOrder.process = #{purchaseOrder.process}"),
    createValueExpression("(select concat(company.companyCode, project.projectCode) from BillingCode as billingCode join billingCode.project as project join project.company as company join billingCode.lineItem as lineItem where lineItem.purchaseOrder = purchaseOrder)) like #{purchaseOrderQuery.preppedBillingCode}"),
    createValueExpression("purchaseOrder.dateNeeded > #{purchaseOrderQuery.preppedDateNeededRange}")
};

this.setRestrictions(Arrays.asList(restrictionsArray));

Очевидно, проблема возникает в этом ограничении createValueExpression("(select concat(company.companyCode, project.projectCode) from BillingCode as billingCode join billingCode.project as project join project.company as company join billingCode.lineItem as lineItem where lineItem.purchaseOrder = purchaseOrder)) like #{purchaseOrderQuery.preppedBillingCode}"), потому что подзапрос возвращает более одного результата. Я предполагаю, что это может быть еще один вопрос, есть ли другой способ сделать что-то вроде запроса «в подобном»? Где параметр выполняет поиск для каждого результата в подзапросе?


person Christian Desserich    schedule 20.12.2011    source источник
comment
Мне любопытно, почему вы пишете свои запросы на EL?   -  person viktor    schedule 21.12.2011
comment
Насколько мне известно, это всего лишь часть использования EntityQuery Seam. По большей части я слежу за тем, как предыдущие разработчики реализуют функции поиска. Насколько я понимаю, EL позволяет динамически изменять входные данные для значений поиска. Если выражение EL принимает значение null, ограничение игнорируется. Структура приложений Seam ‹ -- Это показывает конфигурацию в XML, но настройка в коде Java аналогична.   -  person Christian Desserich    schedule 21.12.2011


Ответы (1)


Я не говорю, что это будет быстрое решение, но чтобы решить проблему выбора подзапроса n результатов, вы можете обойти это следующим образом:

вместо того, чтобы писать

выберите PurchaseOrder из PurchaseOrder в качестве PurchaseOrder, где (выберите concat(company.companyCode, project.projectCode) из BillingCode в качестве billingCode, присоединитесь к billingCode.project в качестве проекта, присоединитесь к project.company, поскольку компания присоединится к billingCode.lineItem в качестве lineItem, где lineItem.purchaseOrder = PurchaseOrder)) например #{purchaseOrderQuery.preppedBillingCode}

использовать

выберите PurchaseOrder из PurchaseOrder как PurchaseOrder, где PurchaseOrder IN (выберите po из PurchaseOrder, чтобы присоединиться к тому, что вам нужно здесь, где что-то вроде # {input})

так что ограничение будет

PurchaseOrder IN (выбрать с лайком)

person Martin Frey    schedule 21.12.2011
comment
Спасибо, это то, как я это реализовал в настоящее время, и это отлично работает, если есть точное совпадение, но клиент хочет, чтобы поиск был похожим. Я могу просто сказать, что это слишком сложно сделать в рамках. Я почти уверен, что могу сделать это в обычном SQL, но тогда я теряю простоту функциональности шва/гибернации, которая заставляет списки разбиваться на страницы и выполнять поиск правильно. Я уверен, что смогу найти обходной путь, но мне нужно двигаться дальше. Возможно, им просто придется принять поиск. - person Christian Desserich; 21.12.2011
comment
Подождите, я не прочитал это достаточно внимательно. Я думаю, что ошибка, на которую я ссылался в своем посте, мешает мне это сделать. Hibernate плохо обрабатывает псевдонимы в подзапросах. Тем не менее, я попробую этот подход еще немного и вернусь к вам. - person Christian Desserich; 21.12.2011
comment
Бум! Спасибо, Мартин! Этот подход отлично работает. Прямо сейчас с моими тестовыми данными это быстро, но я надеюсь, что это не будет супер медленно, когда они получат свои 30 000+ записей. Если это так, я полагаю, они могли бы просто отказаться от подобной функциональности. - person Christian Desserich; 21.12.2011