HQL для получения списка различных сущностей в отношениях «один ко многим» - PullRequest
1 голос
/ 26 марта 2012

В моем приложении пользователи могут генерировать запросы на вещи, поэтому у меня есть две сущности: Запрос и Пользователь, сопоставляемые с базовыми таблицами с одинаковыми именами.Существует отношение многие к одному, так что пользователь может сделать много запросов.Поэтому объект «Мой запрос» выглядит так:


    @Entity
    @Table(name="request")
    public class Request implements Serializable {
        private int id;
        private User requester;

        @Id
        @Column(name="ID", unique=true, nullable=false)
        public int getId() {
            return this.id;
        }

        @ManyToOne(fetch=FetchType.EAGER)
        @JoinColumn(name="REQUESTER", nullable=false)
        public User getRequester() {
            return this.requester;
        }
    }

Мне нужно получить список всех пользователей, которые сделали хотя бы один запрос.

Я пробовал следующее:


    public List<User> retrieveAllRequesters() {
        return hbSession().createQuery("select requester from Request r left join r.requester as requester").list();
    }

но это возвращает сущность для каждого запроса

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


       select distinct requester from Request r left join r.requester as requester

, но это привело к синтаксису HQLошибка

Я пробовал несколько других вещей, меняя left объединение на внутреннее и внешнее , но безуспешно.

Буду признателен за предложение HQL сделать то, что мне нужно.Спасибо.

Богемиан предположил, что это может быть проблемой диалекта, поэтому я включил hibernate.show_sql, и он показывает следующее:

Hibernate: 
    select
        distinct user1_.ID as ID10_,
        user1_.EMAIL_ADDRESS as EMAIL2_10_,
        user1_.EXTERNAL_ID as EXTERNAL3_10_,
        user1_.IS_ADMINISTRATOR as IS4_10_,
        user1_.IS_SUPERVISOR as IS5_10_,
        user1_.IS_TECHNICIAN as IS6_10_,
        user1_.LAST_CHECKED_IN_AT as LAST7_10_,
        user1_.LAST_LOGGED_IN_AT as LAST8_10_,
        user1_.LAST_UPDATED_AT as LAST9_10_,
        user1_.NAME as NAME10_,
        user1_.UI_PREFERENCES as UI11_10_ 
    from
        request request0_ 
    inner join
        [user] user1_ 
            on request0_.REQUESTER=user1_.ID
2255 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 421, SQLState: S0001
2255 [main] ERROR org.hibernate.util.JDBCExceptionReporter - The text data type cannot be selected as DISTINCT because it is not comparable.

База данных MS SQL Server.

Ответы [ 2 ]

3 голосов
/ 26 марта 2012

С HQL вам не нужно «присоединяться» - оно уже неявно присоединено.Попробуйте это:

return hbSession()
   .createQuery("select distinct r.requester from Request r")
   .list();

Отредактировано

Из недавнего дополнения к вопросу, ключевой момент которого:

The text data type cannot be selected as DISTINCT because it is not comparable

, кажется, что еще один битХромой код от Microsoft *sigh* (с этим может справиться любая база данных, с которой я когда-либо работал - это еще одна причина, по которой я никогда не использовал MS SQL)

Вам придется либо изменить тип данныхстолбцы text и varchar (что-то), или используют substring(1, n) на них (в HQL), чтобы сократить их до чего-то, что бедный MS SQL может «сравнить»

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

Большое спасибо Богемяну за то, что он указал мне правильное направление. Его превосходный ответ заслуживает еще одного голосования.

Да, это было ограничение MS SQL Server, в частности его неспособность обрабатывать «текстовые» поля с отличным , но я больше не понимал, что различается будет сравнивать все поля возвращаемого объекта, а не только поле идентификатора.

Поэтому для меня ответ состоял в том, чтобы перенастроить мой HQL таким образом, чтобы он возвращал только интересующие меня поля, а не всю сущность User. Вот как это выглядит сейчас:

    public List<Object[]> retrieveAllRequesters() {
        return hbSession().createQuery("select distinct r.requester.id, r.requester.name from Request r").list();
    }
...