Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate чистый sql: маппинг для подклассов (join entity/table) / 10 сообщений из 10, страница 1 из 1
20.01.2014, 05:34
    #38531330
arkham.vm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate чистый sql: маппинг для подклассов (join entity/table)
Здравствуйте.
Есть 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
20.01.2014, 05:40
    #38531332
arkham.vm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate чистый sql: маппинг для подклассов (join entity/table)
Не получается отредактировать сообщение, в первом листинге есстественно маппинг указан:

Код: 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
20.01.2014, 11:02
    #38531484
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate чистый sql: маппинг для подклассов (join entity/table)
Вполне ожидаемо при использовании SQL запроса.
Используйте HQL и Criteria API вместо этого.
Для управления гибкого управления ассоциациями используйте Fetch Mode.

Или зачем вам вообще Hibernate если вы все Join-ы хотите вручную писать?
...
Рейтинг: 0 / 0
21.01.2014, 02:43
    #38532624
arkham.vm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate чистый sql: маппинг для подклассов (join entity/table)
BlazkowiczИли зачем вам вообще Hibernate
Для кэширования первого/второго уровней.
Blazkowiczвы все Join-ы хотите вручную писать?
Потому что в сильнонагруженной базе данных вручную оптимизированный запрос будет исполняться быстрее.
...
Рейтинг: 0 / 0
21.01.2014, 09:52
    #38532732
Atum1
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate чистый sql: маппинг для подклассов (join entity/table)
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
21.01.2014, 11:10
    #38532827
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate чистый sql: маппинг для подклассов (join entity/table)
arkham.vmДля кэширования первого/второго уровней.

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

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

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

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

+1

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

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

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

jdbctemplate тут накой?

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

Это никак не исправит проблемы.
...
Рейтинг: 0 / 0
23.01.2014, 03:18
    #38535098
arkham.vm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate чистый sql: маппинг для подклассов (join entity/table)
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
23.01.2014, 09:27
    #38535179
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate чистый sql: маппинг для подклассов (join entity/table)
arkham.vmBlazkowiczИли зачем вам вообще Hibernate Для кэширования первого/второго уровней.Blazkowiczвы все Join-ы хотите вручную писать? Потому что в сильнонагруженной базе данных вручную оптимизированный запрос будет исполняться быстрее.
Налицо явное заблужение, даже несколько
- в native SQL запросах кеширование не используется, скорее всего, и его результаты не попадут в кеш
- парсер hibernate достаточно хорошо оптимизирован, и вряд ли получится написать запрос оптимальнее, чем это делает hibernate. В документации рекомендуют применять SQL только для использования фич конкретной СУБД. Естественно, при неправильном маппинге может быть все что угодно.

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

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


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