Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / динамическая выборка с criteria API / 13 сообщений из 13, страница 1 из 1
26.04.2013, 09:11:05
    #38240950
DDiver
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
Есть определенный набор полей, пользователь может выбирать из них необходимые ему, изменять последовательность и в соотвествии с этим получать xls документ.
Всё было бы отлично, но основной документ имеет как many-to-one так и many-to-many зависимости, из-за этого когда в список полей добавляется поле, которое находится в такой зависимости, hibernate использует JOIN и при плохом расскалде получаем не одну строчу, а 2 и более.
Сейчас это все работает на Projection, примерно так:
Код: java
1.
2.
3.
Criteria crit = template.getSessionFactory().getCurrentSession().createCriteria(Complaint.class);
patternsHolder.applyPatterns(crit);
List projectionFields =  crit.list();


patternsHolder содержит набор объектов, которые описывают конкретные поля выборки, умеют применять себя к criteria + доп инфа для правильного отображения их в xls.
Как это сейчас:
- есть метод который возвращает набор Pattern'ов типа такого:
Код: java
1.
2.
3.
4.
5.
6.
7.
public class ExcelExportPattern {
    private String caption;
    private String projectionFieldName;
    private String associationPath;
    private String aliasName;
    private boolean spane;
    private boolean multiple = false; }


они описываются в коде и жестко привязаны к версии.
- Пользователю показывается окошко с этим списком(соответственно обработанным), где он выбирает что и как ему нужно.
- Полученный список Pattern'ов через patternsHolder используется для создания criteria и получения списка List<Object[]> из которого в дальнейшем и рисуется xls

Тут видимо проблема в самом подходе, мне кажется решить проблему при таком способе просто не удастся.
Пытался придумать другой вариант организации, но ничего в голову не приходит.
Может кто подскажет идею как такое можно сделать?
Так как от версии к версии набор полей в объектах меняется, нужно как-то делать так, чтобы сопровождать это можно было просто добавив/удалив/изменив набор соответствующих паттернов, ну или что-то вроде.

Буду признателен за какие-либо идеи.
-----
Предоставленные сами себе события имеют тенденцию развиваться от плохого к худшему.(с)Мерфи
...
Рейтинг: 0 / 0
26.04.2013, 09:54:44
    #38241020
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
Раз есть отношения many-to-one и many-to-many, значит, в "основной" таблице имеются поля, содержащие не одно значение, а коллекцию. Вот и надо их выводить как одно поле, но с перечислением элементов коллекции, тогда все уместится в 1 запись.
Для того, чтобы criteria API возвращал это в виде 1 записи, необходимо сделать правильный мэппинг, но тут подсказать что-то можно только увидев схему данных.
Вот например, такая схема
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
CREATE TABLE H_Office (
       ID                   NUMBER NOT NULL,
...
       PRIMARY KEY (ID)
);

CREATE TABLE H_Office_Option (
       Office_ID            NUMBER NOT NULL,
       Option_Name          VARCHAR(30) NOT NULL,
       PRIMARY KEY (Office_ID, Option_Name)
);

ALTER TABLE H_Office_Option
       ADD FOREIGN KEY (Office_ID)
                             REFERENCES H_Office  (ID)
                             ON DELETE CASCADE;


А вот так её можно отобразить в объекты:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<hibernate-mapping>
	<class name="megadata.HOffice" table="H_OFFICE">
		<id name="id" type="java.lang.Long">
			<column name="ID" precision="22" scale="0" />
			<generator class="sequence">
				<param name="sequence">GEN_H_OFFICE</param>
			</generator>
		</id>
...
		<set name="options" table="H_OFFICE_OPTION" cascade="all">
			<key column="OFFICE_ID" />
			<element type="java.lang.String" column="OPTION_NAME"
				not-null="true" length="30" />
		</set>
	</class>
</hibernate-mapping>


Для таблицы H_OFFICE_OPTION даже нет мэппинга и отдельного класса, она вся в виде коллекции попала в поле основной таблицы:
Код: java
1.
    private Set<String> options = new HashSet<String>();


Остается только решить вопрос как вывести коллекцию в ячейку Excel, но это, думаю, не проблема
...
Рейтинг: 0 / 0
26.04.2013, 10:17:12
    #38241053
DDiver
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
ivanra,
т.к. система уже работает, переделывать мапинги уже позняк, может когда нова версия будет, тогда посмотрю.
на данный момент мапинги такого вида:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
<hibernate-mapping package="xxx.yyy.zzz" default-access="field">
    <class name="Complaint" table="COMPLAINTS">
        <id name="id" column="ID" access="field">
            <generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
                <param name="sequence_name">SSEQUENCE</param>
            </generator>
        </id>
…
        <list name="appealDocs" table="COMPL_APP_DOCS_LINKS" lazy="true" cascade="all-delete-orphan">
            <key column="COMPLAINT_ID"/>
            <list-index column="SORTIDX"/>
            <many-to-many column="APPEALDOC_ID" class="ComplaintAppealDoc" unique="true"/>
        </list>
…
        <set name="appealTaxType" table="COMPL_TAX_TYPE_LINKS" lazy="true" cascade="save-update">
            <key column="COMPLAINT_ID"/>
            <many-to-many column="TAX_TYPE_ID" entity-name="ComplAppealTaxType" unique="false"/>
        </set>
…
    </class>
</hibernate-mapping>


ищу решение исходя из текущих реалий.
...
Рейтинг: 0 / 0
26.04.2013, 10:17:46
    #38241055
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
Код: java
1.
crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);


Или я не понял вопроса?
...
Рейтинг: 0 / 0
26.04.2013, 10:37:29
    #38241092
DDiver
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
Blazkowicz
Код: java
1.
crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);


Или я не понял вопроса?
наверное не поняли, или я не так описал.
патерны применяются к критерии вот так
Код: java
1.
2.
3.
4.
5.
ProjectionList projectionList = Projections.projectionList();
for(…) {
  projectionList.add(Property.forName(pattern.getProjectionFieldName()));
}
criteria.setProjection(projectionList);


и т.к. crit.list() возвращает не сам объект Complaint, то и никакого DISTINCT_ROOT_ENTITY не происходит. Возвращается банальный набор List<T[]>, который является отображения результата select'а.
как-то так.
...
Рейтинг: 0 / 0
26.04.2013, 10:53:53
    #38241116
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
DDiver,

Понял. Но вы всё равно хотите Distinct, ведь, по какому-то полю? Можно реализовать свой ResultTransformer, для пособработки результата. Или добавить Projection с Distinct по какому-то полю
С другой стороны не понятно в чем тут смысл? Так как у вас нет сущностей, то вы не сможете из результата джоина собрать ассоциации.
Выходит где-то проблема в постановке задачи.
Во-первых Hibernate это ORM. Если вы работаете с отдельными полями без сущностей, возможно, Hibernate - не совсем правильный выбор.
Во-вторых объясните какой именно результат вы ожидаете. Вот есть пользовате выбирает Заказ и Товары. У одного заказа несколько товаров. Как вы хотите это отобразить в XLS?
...
Рейтинг: 0 / 0
26.04.2013, 11:10:21
    #38241134
DDiver
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
Blazkowicz,
мне тоже кажется что использование полей без сущностей плохой вариант, но как выбирать у сущности только выбранные пользователем поля, я себе пока представить не могу. Если как-то это сделать, то тут проблема сама уйдет.
По поводу отображения:
выглядит вот так примерно
...
Рейтинг: 0 / 0
26.04.2013, 11:11:54
    #38241137
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
BlazkowiczВот есть пользовате выбирает Заказ и Товары. У одного заказа несколько товаров. Как вы хотите это отобразить в XLS?
товары можно через запятую. Если заказчик согласен.
Но, вы правы - это уже не ОРМ. В РСУБД \ на клиенте делают свёртку-процедуру по полю = в один стринг.
Хотя это можно сделать и XLS.
Ведь XLS это Представление модели.
...
Рейтинг: 0 / 0
26.04.2013, 11:19:44
    #38241148
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
DDiverПо поводу отображения:
выглядит вот так примерно
Как вы его формируете? Если руками, то:
- объединить ячеки Количество = Count подчинённых полей
- вписать в эту ячеку
- вписать коллекцию
- перейти на след Мастер-запись
...
Рейтинг: 0 / 0
26.04.2013, 11:32:38
    #38241171
DDiver
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
Petro123,
руками с небольшим шаманством :)
проблема возникает в том, что когда у основного объекта в двух разных коллекциях есть более одного объекта. Невозможно узнать какая именно коллекция наплодила дублей.
[Заказ1;(Товар1,Товар2);Цена;(Телфон1,Телефон2)] выдаст 4 строки соответственно.
в выходных данных отличить его от [Заказ1;(Товар1,Товар2,Товар3,Товар4);Цена;(Телфон1)], который тоже даст 4 строки не получится.
Можно конечно вытаскивать ещё и ID объектов коллекций, и ориентируясь по ним решать что именно двоится, но мне кажется это совсем через одно место способ.
...
Рейтинг: 0 / 0
26.04.2013, 12:18:47
    #38241267
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
DDiver,
ОРМ применяют для CRUD а не для Отчётных систем.
Без ОРМ это решается ОДНИМ запрорсом на Отчёт с добавлением 3 раза:
SELECT AAAA GROUP BY, GROUP BY, GROUP BY
Удачи!
...
Рейтинг: 0 / 0
26.04.2013, 12:21:18
    #38241271
DDiver
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
Petro123DDiver,
ОРМ применяют для CRUD а не для Отчётных систем.
Без ОРМ это решается ОДНИМ запрорсом на Отчёт с добавлением 3 раза:
SELECT AAAA GROUP BY, GROUP BY, GROUP BY
Удачи!
да не отчетная это система, просто заказчик хочет иметь возможность выгрузки данных в сыром виде из БД(зачем не спрашивайте), вот это и делает мой алгоритм.
Сейчас пробую ещё один вариант, если получится то напишу что придумал :)
...
Рейтинг: 0 / 0
26.04.2013, 15:06:12
    #38241654
DDiver
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
динамическая выборка с criteria API
Ну что же, изменив метод смог реализовать задуманное.
Забил на вытаскивание конкретных столбцов из БД, тащу сразу сущности. Написал класс, который полученную жалобу вычитывает и сохраняет в определенном виде, удобно для доступа из вне по имеющимся метаданным. Ну а далее бежим по списку паттернов, вытаскиваем нужные данные из класса-обертки и рисуем жалобу в xls.

ЗЫ Вот что форум животворящий в пятницу делает :)
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / динамическая выборка с criteria API / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]