powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate, Mapping & Postgres
17 сообщений из 17, страница 1 из 1
Hibernate, Mapping & Postgres
    #39437626
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день,

Дано: данные в разных таблицах, которые представляют собой некое дерево Hibernate сущностей (c 1:1 и 1:N связями). К примеру A и B находятся в отношении 1:N :
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@Entity
class A {
     private Integer id; 
}

@Entity
class B {
     @Column(name = "a_id")
     private Integer a;
}


Как видно из примера связь между сущностями не является класической Hibernate связью. Все это данность. Поменять нельзя.

Задача: одним запросом вычитать A + связанные B (т.к. 1:N) причем каждая строка результата должна содержать A + связанные B.

Pешение:
На уровне DB это относительно просто:
Код: plsql
1.
2.
3.
select a.*,
         (select array_agg(b.*) from b where b.a_id= a.id) as b
     from a



Проблема заключается в том как результаты данного найтив запроса можно перегнать в сущности.

Делаю так:
Код: java
1.
2.
3.
Query query = session.createSQLQuery(sql)
					.addEntity("a", A.class)
                                        .addScalar("b", MyCollectionTypeOfB.class);


где
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
public class MyCollectionTypeOfB implements UserType {

	@Override
	public Class<B[]> returnedClass() {
		return B[].class;
	}

	@Override
	public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
		PgArray pgArray = (PgArray)rs.getObject(names[0]);

		for(Object object: (Object[])pgArray.getArray()){
			PGobject pgObject = (PGobject) object;
			String value = pgObject.getValue();

		}


		return pgArray.getArray();
	}
        ..............
}



Собственно проблема заключается в том что
Код: java
1.
String value = pgObject.getValue();


Это просто строковая сериалицация массива элементов типа B.

Вопрос: каким образом мне получить джава объекты A + связанные B?
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437664
Nixic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А почему у вас в классе "B" переменная "a" имеет тип Integer, она же должна быть типа "A".

типа вот так вот:

Код: java
1.
2.
3.
4.
5.
@Entity
class B {
   //  @Column(name = "a_id")
     private A a;
}



и @Column(... вам тогда и не нужен будет, хибер сам создаст, если нет еще такого поля в таблице, a_id, а если есть, то будет работать с существующим. Причем создаст именно с таким именем.
По запросу мне особо нечего сказать, так как использую обычно самые простые селекты, максимум с джойнами. Ждите других комментов :)
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437665
Nixic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А да, аннотацию забыл поставить
Код: java
1.
2.
3.
4.
5.
6.
@Entity
class B {
   //  @Column(name = "a_id")
     @ManyToOne  // можно еще лейзи добавить в скобках, если нужно (fetch = FetchType.LAZY)
     private A a;
}
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437667
Nixic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bemtaillКак видно из примера связь между сущностями не является класической Hibernate связью. Все это данность. Поменять нельзя.

Не обратил внимания, беру свои комменты тогда обратно :)
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437715
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Исправлять меппинг. Необходимость выполнения приведенных выше запросов подтверждает, что меппинг сделан с ошибками.
Если совсем нельзя - смотреть в сторону NamedQuery, может, там удастся правильно замепить
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437736
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблему не очень понял
bemtaillЭто просто строковая сериалицация массива элементов типа B.

Вопрос: каким образом мне получить джава объекты A + связанные B?

Наверное ответ очевиден: десериализовать

А вот как это сделать, я не знаю, просто не делал. Читать документацию и сорцы PG. Формат raw данных как минимум можно посмотреть в C-ных сорцах, как реализовать объект B на Java - посмотреть как реализованы стандартные PG классы (PGbox, PGcircle, PGInterval, ... etc.)

Сомневаюсь, что Hibernate такое умеет. Т.к. такой финт ушами явно не переносим между разными БД. А Hibernate все таки кросс-бд среда
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437778
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за ответы.
Перед тем как постить вопрос я изучил все варианты и пришел к тем же выводам, но подумал что может я что-то упустил и можно сделать проще. Писать кастом десериалайзер для каждой сущности это проблематично, т.к. в реальности все сущности имеет конечно более сложную структуру. Была надежда что можно каким-то образом десериализовывать PGobject'ы используя Hibernate маппинг для этих объектов. Но похоже не получится и кроме как парсить строку другого выхода нет при данном подходе. Сделать правильный маппинг между сущностями не получится - это работы на год. Посмотрю как можно еще решить эту задачу с других сторон.
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437826
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
что-то типа такого
Код: java
1.
2.
3.
4.
class AExtended extends A {
	Set<B> setB;
	//getter+setter
}


Код: xml
1.
2.
3.
4.
5.
6.
7.
<sql-query name="my.named.query">
	<return class="my.package.AExtended"/>
	<load-collection alias="b" role="setB" />
	<![CDATA[
select {a.*},{b.*} from a inner join b on b.a_id=a.id where ...bla bla bla
	]]>
</sql-query>
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437871
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
bemtaill,
второпях не тот тег поставил. должно быть return-join
Код: xml
1.
2.
3.
4.
5.
6.
7.
<sql-query name="my.named.query">
	<return alias="a" class="my.package.AExtended"/>
	<return-join alias="b" property="a.setB" />
	<![CDATA[
select {a.*},{b.*} from a inner join b on b.a_id=a.id where ...bla bla bla
	]]>
</sql-query>
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437908
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bemtaill...Писать кастом десериалайзер для каждой сущности это проблематично...

Для каждой и не надо. Надо парсер для стандартных типов которые встречаются в таблице. Строка таблица состоит обычно из этих типов.

В Oracle, например, есть стандартная утилита пре-процессор, которая позволяет получать Java-обертки над объектами созданными в БД. Сделать универсальный десериалайзер или, на худой конец, свой генератор кода - вполне реально.

IMHO Совершенно нормальная и понятная задача. С трудозатратами от недели до нескольких месяцев. Но ни как не годы.
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437912
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev,
Годы он говорил про исправление модели в базе.
Т.к. в базе нет смысла депжать сериализацию.
А если держать, то не делать запросы и маппинг.
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437924
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Годы он говорил про исправление модели в базе.

Я не очень вижу, где в БД не та модель.

Код: plsql
1.
2.
3.
select a.*,
         (select array_agg(b.*) from b where b.a_id= a.id) as b
     from a



A и B - совершенно классическая связь 1 : N

Другое дело, что стандартным SQL задачу:

" одним запросом вычитать A + связанные B (т.к. 1:N) причем каждая строка результата должна содержать A + связанные B"
В общем случае - не решить. Спасибо теоретикам реляционных баз данных. Были они больно умными и сильно далеки от народа.
(вариант ivanra имеет ряд ограничений и недостатков)

Другое дело, что нарушив правила нормализации и использовав ф-ции/возможности конкретной БД - вполне можно. Но вот здесь проблема. Что такие возможности, скорее всего (не смотрел), ни в ANSI SQL, ни в JDBC в полной мере не предусмотрены. Т.е. нужно делать "ручками" и код будет не переносимый между БД.

Проблему я так понял. Может ошибаюсь.
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437935
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev,

Стандарт это же 2 таблы так же как и 2 класса по UML
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39437937
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тоже не пойму задачу.)))
Один запрос это одно множество. Исходных по моделт 2 множества.....
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39438001
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати, раз уж речь про postgresql, то данные из подчиненной таблицы можно засериализовать в xml/json, а на клиенте распарсить с помощью jaxb
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39438346
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
{quote}
Я не очень вижу, где в БД не та модель.
{quote}

В бд та, в коде не та. Посмотрите комментарии от Nixic.

{quote}
Проблему я так понял. Может ошибаюсь.
{quote}
Да, абсолютно верно.

{quote}
Кстати, раз уж речь про postgresql, то данные из подчиненной таблицы можно засериализовать в xml/json, а на клиенте распарсить с помощью jaxb
{quote}
Вы правы, но это не решает проблему из-за наличия различий в названии полей сущностей и названия столбцов в БД.
{code}
@Column(name = "a_id")
private Integer a;
{code}
...
Рейтинг: 0 / 0
Hibernate, Mapping & Postgres
    #39438348
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
блин, привык к Confluence ))

Я не очень вижу, где в БД не та модель.
В бд та, в коде не та. Посмотрите комментарии от Nixic.

Проблему я так понял. Может ошибаюсь.
Да, абсолютно верно.

Кстати, раз уж речь про postgresql, то данные из подчиненной таблицы можно засериализовать в xml/json, а на клиенте распарсить с помощью jaxb
Вы правы, но это не решает проблему из-за наличия различий в названии полей сущностей и названия столбцов в БД.
Код: java
1.
2.
@Column(name = "a_id")
private Integer a;
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate, Mapping & Postgres
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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