Hibernate "присоединиться", извлекая странное поведение - PullRequest
2 голосов
/ 14 марта 2012

У меня есть пользователь и таблица сообщений. Пользователь-сообщение - это отношения один-ко-многим, а сообщение-пользователь - это отношения многие-к-одному. Я пометил один из многих к одному как выборку соединения. Когда я «получаю» одно сообщение, Hibernate запускает запрос на соединение, но когда я получаю все сообщения, Hibernate запускает запросы на выборку вместо соединения. Что может быть причиной? Ниже приведены подробности:

Отношения между ними:

Пользователь

<set name="messagesForFromUserUid" lazy="true" table="message" inverse="true" cascade="save-update">
        <key>
            <column name="from_user_uid" not-null="true" />
        </key>
        <one-to-many class="repository.Message" />
    </set>
    <set name="messagesForToUserUid" lazy="true" table="message" fetch="select">
        <key>
            <column name="to_user_uid" not-null="true" />
        </key>
        <one-to-many class="repository.Message" />
    </set>

Сообщение

<many-to-one name="userByFromUserUid" class="repository.User" fetch="join" lazy="false">
        <column name="from_user_uid" not-null="true" />
    </many-to-one>
    <many-to-one name="userByToUserUid" class="repository.User" fetch="select" lazy="proxy">
        <column name="to_user_uid" not-null="true" />
    </many-to-one>

Когда я выбираю один объект сообщения, Hibernate запускает один запрос на соединение, как и ожидалось:

Message m = (Message) s.get(Message.class, 2);

Hibernate: 
select
    message0_.message_uid as message1_1_1_,
    message0_.from_user_uid as from2_1_1_,
    message0_.to_user_uid as to3_1_1_,
    message0_.message_text as message4_1_1_,
    message0_.created_dt as created5_1_1_,
    user1_.user_uid as user1_0_0_,
    user1_.user_name as user2_0_0_,
    user1_.user_password as user3_0_0_,
    user1_.email as email0_0_,
    user1_.first_name as first5_0_0_,
    user1_.last_name as last6_0_0_,
    user1_.created_dt as created7_0_0_ 
from
    hello.message message0_ 
inner join
    hello.user user1_ 
        on message0_.from_user_uid=user1_.user_uid 
where
    message0_.message_uid=?

Но когда я получаю все сообщения за один раз, Hibernate вместо этого запускает запросы на выборку:

List<Message> l = s.createQuery("from Message").list();

Hibernate: 
select
    message0_.message_uid as message1_1_,
    message0_.from_user_uid as from2_1_,
    message0_.to_user_uid as to3_1_,
    message0_.message_text as message4_1_,
    message0_.created_dt as created5_1_ 
from
    hello.message message0_
Hibernate: 
select
    user0_.user_uid as user1_0_0_,
    user0_.user_name as user2_0_0_,
    user0_.user_password as user3_0_0_,
    user0_.email as email0_0_,
    user0_.first_name as first5_0_0_,
    user0_.last_name as last6_0_0_,
    user0_.created_dt as created7_0_0_ 
from
    hello.user user0_ 
where
    user0_.user_uid=?

Hibernate: 
select
    user0_.user_uid as user1_0_0_,
    user0_.user_name as user2_0_0_,
    user0_.user_password as user3_0_0_,
    user0_.email as email0_0_,
    user0_.first_name as first5_0_0_,
    user0_.last_name as last6_0_0_,
    user0_.created_dt as created7_0_0_ 
from
    hello.user user0_ 
where
    user0_.user_uid=?

Ответы [ 2 ]

2 голосов
/ 25 марта 2012

Похоже, что Hibernate не всегда использует стратегии выборки, определенные в отображении, для запросов HQL или Criteria.Они обычно используются для получения / загрузки.Нашел ссылку здесь: https://forum.hibernate.org/viewtopic.php?f=1&t=957561

0 голосов
/ 14 марта 2012

Я не уверен, но это может быть причиной.Если вы запускаете один запрос, который является присоединением или подзапросом.Это нормально, для одного запроса не может быть разницы в производительности.Но если вы выполняете несколько запросов (в вашем случае несколько сообщений), там может возникнуть проблема производительности.Я определенно выбрал бы простые запросы выбора вместо соединений / подзапросов.Это определенно имеет смысл, если мы рассмотрим производительность.Это то, что делает Hibernate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...