Hibernate 6 Left加入收藏最新成员

mjqavswn  于 2023-10-23  发布在  其他
关注(0)|答案(1)|浏览(102)

在Hibernate 6.2中,如果有一本匹配的书,我想用最新的Book获取一个Author实体,并将其转换为Dto投影-AuthorBookDto

作者

public class Author {
@Id
@GeneratedValue(strategy = SEQUENCE, generator = "author_seq")
private Long id;

@JsonBackReference
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "author")
private List<Book> listBook = new ArrayList<>();

// other fields
// getters and setters

预订

public class Book {

@Id
@GeneratedValue(strategy = SEQUENCE, generator = "book_seq")
private Long id;

@JsonManagedReference
@ManyToOne(fetch = FetchType.EAGER, optional = false)
private Author author;    

private LocalDateTime publishedDateTime;

我想投影到的Dto包含来自Author的一些字段和来自Book集合的最新Book

AuthorBookDto

public class AuthorBookDto {

// Selected fields from Author plus a book entity (the newest one)
public Long authorId;
public Long bookId;
public Book newestBook;

我写了一个查询,只要选择一个Author,就可以从Book中检索单个字段,但不能检索整本书实体(下面的查询不能正确投影到上面的实体):

public Test customQuery3(Long id) {
    return (Test) entityManager.createQuery(
                    "SELECT NEW com.view.Test(a.id, a.name, y.pub_max_date) FROM Author a " +
                            "LEFT JOIN(SELECT book.id as book_id, MAX(book.pubDateTime) as pub_max_date, book.author.id as bid FROM Book b WHERE book.author.id=:id) as y " +
                            "ON a.id=y.bid " +
                            "WHERE a.id=:id GROUP BY a.id, y.book_id ORDER BY y.pub_max_date DESC LIMIT 1")
            .setParameter("id", id)
            .getSingleResult();

结果应该如下所示:

{
    "id": 1,
    "name": "Steven King",
        Book {"id": "1",
              "title":"The Shining",
              "publishedDateTime":"2023-01-01 13:00"
              }
 }

这在一个HQL查询中可能吗?(注:有些作者可能没有出版过任何书籍)

w1jd8yoj

w1jd8yoj1#

此查询的工作原理:

@Override
public Test customQuery3(Long id) {
    return (Test) entityManager.createQuery(
                    "SELECT NEW com.view.Test(a.id, b) FROM Author a " +
                            "LEFT JOIN Book b ON b.author.id=a.id " +
                            "WHERE b.id=:id " +
                            "GROUP BY a, b ORDER BY b.newestBook DESC LIMIT 1")
            .setParameter("id", id)
            .getSingleResult();
}

b.newestBook上的排序将最新的放在顶部,.getSingleResult()LIMIT 1都确保只返回1个结果。

相关问题