Использование нового конструктора в hql-запросе не может найти правильный констурктор или не может извлечь ResultSet - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть объекты:

@Entity
public class Author{
    @ManyToMany(cascade = { CascadeType.ALL })
    @JoinTable(
            name = "author_book",
            joinColumns = { @JoinColumn(name = "author_id") },
            inverseJoinColumns = { @JoinColumn(name = "book_id") }
    )
   public List<Book> books;
}

@Entity
public class Book{
   @ManyToMany(mappedBy = "books")
   public List<Author> authors;

   @OneToMany(mappedBy = "book")
   public List<Fact> facts;

   public Book(){}
   public Book(List<Author> authors, List<Fact> facts){
       this.authors = authors;
       this.facts = facts;
   }
}

@Entity class Fact{
   @ManyToOne
   @JoinColumn(name="book_id")
   public Book book;
}

В книге больше авторов, и авторы могут писать больше книг.В каждой книге есть больше фактов об этом, и каждый акт принадлежит только одной книге.

Теперь я хочу получить объект типа Book на основе идентификатора автора.Объект типа Book должен содержать всех авторов и все факты.

Я использую запрос гибернации для этого:

List<Book> books = (List<Book>) session.createQuery("Select new Book (books.authors, books.facts ) FROM Author u JOIN u.books books JOIN books.facts WHERE u.id IN :ids ").setParameter("ids", authorId).list();

Однако это приводит к ошибке:

Невозможно найти соответствующий конструктор в классе [Book].Ожидаемые аргументы: java.util.Collection, java.util.Collection

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

   public Book(Object authors,Object facts){
       this.authors = (List<Author>)authors;
       this.facts = (List<Fact>)facts;
   }

Но это жалуется:

org.hibernate.exception.SQLGrammarException: не удалось извлечь ResultSet

Каков правильный способ получения сущности с требуемыми данными тогда?Жалуется только на отношения (например, коллекции), я нигде не нашел решения для этого (ни документации для hql).

Спасибо за помощь!

1 Ответ

0 голосов
/ 29 сентября 2018

Вы не можете использовать НОВЫЙ оператор с сущностями!

Это для проекции DTO (объекта передачи данных).

В вашем случае вам даже не нужен NEW, потому что вы можете просто выбрать книгу, которая будет построена Hibernate, используя настройки по умолчаниюконструктор и установка полей.

List<Book> books = 
   (List<Book>) session.createQuery(
   "Select books FROM Author u JOIN u.books books JOIN books.facts WHERE u.id IN :ids ")
   .setParameter("ids", authorId).list();

и если вы хотите, чтобы коллекции были загружены, используйте JOIN FETCH, например:

List<Book> books = 
   (List<Book>) session.createQuery(
   "Select b FROM Book b JOIN FETCH b.authors a JOIN FETCH b.facts f WHERE a.id IN :ids ")
   .setParameter("ids", authorId).list();

Важное замечание:

Hibernate не можетс нетерпением получить два спискаТам я предлагаю изменить списки на наборы:

@ManyToMany(mappedBy = "books")
public Set<Author> authors;

@OneToMany(mappedBy = "book")
public Set<Fact> facts;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...