Как мне оставить таблицы соединений в однонаправленном множестве к одному в Hibernate? - PullRequest
8 голосов
/ 05 марта 2010

Я отказываюсь от Как объединять таблицы в однонаправленном режиме «многие к одному»? .

Если у вас есть два класса:

class A {
    @Id
    public Long id;
}

class B {
    @Id
    public Long id;
    @ManyToOne
    @JoinColumn(name = "parent_id", referencedColumnName = "id")
    public A parent;
}

B -> A - это отношение много к одному. Я понимаю, что могу добавить коллекцию B к A, но я не хочу этой ассоциации.

Итак, мой актуальный вопрос: существует ли способ создания SQL-запроса с помощью HQL или критериев:

select * from A left join B on (b.parent_id = a.id)

При этом будут извлечены все записи A с декартовым произведением каждой записи B, которая ссылается на A, и будут включены записи A, на которые нет ссылок B.

Если вы используете:

from A a, B b where b.a = a

тогда это внутреннее соединение, и вы не получите записи A, у которых нет ссылки B на них.

Я не нашел хорошего способа сделать это без двух запросов, поэтому что-нибудь меньшее, чем это, было бы замечательно.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 05 марта 2010

Я сделал пример с тем, что вы написали, и я думаю, что это может работать:

select a,b from B as b left outer join b.parent as a на HQL.

Я должен найти "критерии", способ сделать это, хотя.

1 голос
/ 05 марта 2010

Вы можете сделать это, указав атрибут fetch.

(10) выборка (необязательно) Выбор между извлечением из внешнего соединения и извлечением путем последовательного выбора.

Вы найдете его по адресу: Глава 6. Сопоставление коллекций , прокрутите вниз до: 6.2. Картирование коллекции

EDIT

Я прочитал в комментарии к вашему вопросу, что вы хотели выполнить необработанный SQL-запрос? Вот ссылка, которая может быть интересна:

Глава 13 - Собственные запросы SQL

и если вы хотите, чтобы это было возможно через HQL:

Глава 11. HQL: язык запросов Hibernate

В главе 11 вы хотите прокрутить вниз до 11.3. Ассоциации и объединения .

IQuery q = session.CreateQuery(@"from A as ClassA left join B as ClassB");

Полагаю, однако, что ClassB должен быть членом ClassA. Дальнейшие изменения должны помочь.

Еще одна вещь, которая может оказаться полезной для вас, это именованных запросов :

<query name="PeopleByName">
from Person p
where p.Name like :name
</query>

И вызов этого запроса изнутри кода выглядит так:

using (var session = sessionFactory.OpenSession())
    using (var tx = session.BeginTransaction()) {
        session.GetNamedQuery("PeopleByName")
            .SetParameter("name", "ayende")
            .List();
        tx.Commit();
    }

Пожалуйста, взгляните на ссылочную ссылку Айенде, которая более подробно объясняет это.

...