powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate чистый sql: маппинг для подклассов (join entity/table)
10 сообщений из 10, страница 1 из 1
Hibernate чистый sql: маппинг для подклассов (join entity/table)
    #38531330
arkham.vm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.
Есть sql запрос подобного вида (запрос сильно упрощен для изложеняи сути вопроса):

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
    .createSQLQuery("
       SELECT 
            a.id, a.title, 

            a.type_id as type_content,
            b.type_id as ctid_type, 

            a.city_id as city_id,
            c.city_id as cnid
 
        FROM articles as a 
        INNER JOIN content_type as b ON a.type_id=b.type_id
        INNER JOIN city_list    as c ON a.city_id=c.city_id
        WHERE a.id=1")
    .addScalar("title")
    .....
    .setResultTransformer(Transformers.aliasToBean(Article.class))



Код java класса:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
@SqlResultSetMapping(name="ArticleAndTypeAndCity", entities={
    @EntityResult(entityClass=Article.class, fields = {
        @FieldResult(name="id",         column="id"),
        ......
        
        @FieldResult(name="city",       column="city_id"),
        @FieldResult(name="type",       column="type_content"),
    }),
    @EntityResult(entityClass=ContentType.class, fields = {
        @FieldResult(name="id",         column="ctid_type"),
        ....
    }),
    @EntityResult(entityClass=City.class, fields = {
        @FieldResult(name="id",         column="cnid"),
        .....
    })
    }
)

    @Entity
    @Table(name="articles")
    Class Article ... { 
    ...
            @Column(name="title")
    private String title;
            @OneToOne
            @JoinColumn(name="type_id")
    private ContentType type;
            @OneToOne
            @JoinColumn(name="city_id")
    private Сity city;
    ...
    }

    @Entity
    @Table(name="content_type")
    Class ContentType ... {
    ...
            @Column(name="type_id")
    private Long id;
    ...
    }

    @Entity
    @Table(name="city_list")
    Class City ... {
    ...
            @Column(name="city_id")
    private Long id;
    ...
    }



Проблема в том, что не получается правильно получить результат, либо не достаеться вообще нчиего, либо дотается Article, но переменные подклассов в Article (.getCity(), .getContentType()) оказываются NULL.
Пробовал указывать через .addEntity("cn", CityNames.class) и .addJoin("CityNames","PageContent.city"), но видимо ещё не постиг дао Гибернейта.
Прошу помощи :) Спасибо за ответы.

P.S. Запрос нужно оставить в чистом sql виде по некоторым причинам (реализация кэша, нетривиальная секция WHERE).
...
Рейтинг: 0 / 0
Hibernate чистый sql: маппинг для подклассов (join entity/table)
    #38531332
arkham.vm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не получается отредактировать сообщение, в первом листинге есстественно маппинг указан:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
    .createSQLQuery("
       SELECT 
            a.id, a.title, 

            a.type_id as type_content,
            b.type_id as ctid_type, 

            a.city_id as city_id,
            c.city_id as cnid
 
        FROM articles as a 
        INNER JOIN content_type as b ON a.type_id=b.type_id
        INNER JOIN city_list    as c ON a.city_id=c.city_id
        WHERE a.id=1")
    .setResultSetMapping("ArticleAndTypeAndCity")
    .addScalar("title")
    .....
    .setResultTransformer(Transformers.aliasToBean(Article.class))
...
Рейтинг: 0 / 0
Hibernate чистый sql: маппинг для подклассов (join entity/table)
    #38531484
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вполне ожидаемо при использовании SQL запроса.
Используйте HQL и Criteria API вместо этого.
Для управления гибкого управления ассоциациями используйте Fetch Mode.

Или зачем вам вообще Hibernate если вы все Join-ы хотите вручную писать?
...
Рейтинг: 0 / 0
Hibernate чистый sql: маппинг для подклассов (join entity/table)
    #38532624
arkham.vm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczИли зачем вам вообще Hibernate
Для кэширования первого/второго уровней.
Blazkowiczвы все Join-ы хотите вручную писать?
Потому что в сильнонагруженной базе данных вручную оптимизированный запрос будет исполняться быстрее.
...
Рейтинг: 0 / 0
Hibernate чистый sql: маппинг для подклассов (join entity/table)
    #38532732
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
arkham.vmBlazkowiczИли зачем вам вообще Hibernate
Для кэширования первого/второго уровней.
Blazkowiczвы все Join-ы хотите вручную писать?
Потому что в сильнонагруженной базе данных вручную оптимизированный запрос будет исполняться быстрее.

1)@OneToOne - измените модель базы данных.
2)Хм... опишите свой запрос на HQL - включите дебаг - посмотрите какого вида будет запрос генерировать hibernate.
3)Не используйте hibernate - введите DAO объекты .
4)Используйте jdbctemplate.
5)Опишите Ваш sql как процедуру - вызывайте процедуру ( для скорости ):
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
@NamedNativeQuery(name="getAllArticle",query="{? = call get_all_articles}", callable=true, resultClass=Article.class)
...
//
List article = (List) session.getNamedQuery("entity").list();
...
//
CallableStatement st = session.connection().prepareCall("{call save_article(?,?,?)}");
st.setLong(1,0);
st.setString(2, "text1");
st.setString(3,"text2");
st.registerOutParameter(1, java.sql.Types.NUMERIC);
st.execute();
System.out.println(st.getLong(1));
...
Рейтинг: 0 / 0
Hibernate чистый sql: маппинг для подклассов (join entity/table)
    #38532827
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
arkham.vmДля кэширования первого/второго уровней.

Для кеширования можно просто прикрутить кэш. Первый уровень между логикой и слоем обращения к базе. Второй уровень между слоем обращения к базе и самой базой. Тот же myBatis чего было не взять, если вас так прет на pure SQL всё делать?

arkham.vmПотому что в сильнонагруженной базе данных вручную оптимизированный запрос будет исполняться быстрее.
Ерунда. FetchMode точно так же управляет вашими запросами, при том что предоставляет лёгкий способ поменять JOIN на 2 SELECT запроса или обратно. А на pure SQL вам нужно будет тупо полностью переписывать запрос, чтобы поиметь вместо толстого JOIN несколько мелких зарпосов.
...
Рейтинг: 0 / 0
Hibernate чистый sql: маппинг для подклассов (join entity/table)
    #38532830
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum11)@OneToOne - измените модель базы данных.

Не думаю что автор темы поймет о чем речь.

Atum12)Хм... опишите свой запрос на HQL - включите дебаг - посмотрите какого вида будет запрос генерировать hibernate.

+1

Atum13)Не используйте hibernate - введите DAO объекты .

Ни о чем. Возможно имелось ввиду, "не искпользуйте Hibernate API из слоя бизнес логики напрямую. Оберните всё в отдельный слой DAO"? Вопрос спорный.

Atum14)Используйте jdbctemplate.

jdbctemplate тут накой?

Atum15)Опишите Ваш sql как процедуру - вызывайте процедуру ( для скорости ):

Это никак не исправит проблемы.
...
Рейтинг: 0 / 0
Hibernate чистый sql: маппинг для подклассов (join entity/table)
    #38535098
arkham.vm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Atum1, Blazkowicz, спасибо за ответы.
Я бы с удовольствием отклонился от заданной архитектуры, если бы проект был новым а не n-летней давности. Так что советы в этом плане хоть и полезны, но в данном случае бессмысленны.

автор1)@OneToOne - измените модель базы данных.
Изначально там был @ManyToOne, в соответсвии с моделью данных, но с данной аннотацией маппинг выполняться вообще не пожелал.

автор2)Хм... опишите свой запрос на HQL - включите дебаг - посмотрите какого вида будет запрос генерировать hibernate.
Запрос изначально был на Hibernate функциях Restrictions/Criteria. Включил дебаг, взял сгенеренный запрос, и переписал на более быстрый ручной.

автор3)Не используйте hibernate - введите DAO объекты .
Возможно имелось ввиду, "не искпользуйте Hibernate API из слоя бизнес логики напрямую. Оберните всё в отдельный слой DAO"?

Hibernate API как раз таки и вызывается только из DAO Layer.

автор4)Используйте jdbctemplate.
Если я правильно понял, это аналог трансформеров гибернета, использовать в проекте то одно то другое не очень хочеться, желательно сохранить общий стиль.

автор5)Опишите Ваш sql как процедуру - вызывайте процедуру ( для скорости ):
Проблема не в том как выполнить запрос, пробелма в том, что бы ResultSet правильно странсформировался не только в нужный класс объекта (Article.class), но и используемые в объекте подклассы (ContentType.class, City.class).
...
Рейтинг: 0 / 0
Hibernate чистый sql: маппинг для подклассов (join entity/table)
    #38535179
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
arkham.vmBlazkowiczИли зачем вам вообще Hibernate Для кэширования первого/второго уровней.Blazkowiczвы все Join-ы хотите вручную писать? Потому что в сильнонагруженной базе данных вручную оптимизированный запрос будет исполняться быстрее.
Налицо явное заблужение, даже несколько
- в native SQL запросах кеширование не используется, скорее всего, и его результаты не попадут в кеш
- парсер hibernate достаточно хорошо оптимизирован, и вряд ли получится написать запрос оптимальнее, чем это делает hibernate. В документации рекомендуют применять SQL только для использования фич конкретной СУБД. Естественно, при неправильном маппинге может быть все что угодно.

Можете объяснить, в чем заключалась изначальная неоптимальность запроса из Restrictions/Criteria? Может, достаточно было указаить правильный Fetch Mode?
...
Рейтинг: 0 / 0
Hibernate чистый sql: маппинг для подклассов (join entity/table)
    #38535386
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
arkham.vm,

Попробуйте использовать addEntity вместо addScalar и ResultTransformer.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate чистый sql: маппинг для подклассов (join entity/table)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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