我需要从集合中获取最后一个实体元素。我正在使用@JoinFormula:
@Entity
public class Book {
@ManyToOne
@JoinFormula("(select * from
(SELECT r.id FROM review r WHERE r.book_id = id ORDER BY r.postedAt DESC)
where rownum = 1)")
private Review
...
}
它的效果非常棒,但前提是书有一些评论。否则找不到书。因为 Hibernate 将其转换为交叉连接并在 WHERE 语句中使用条件:
review_entity.id =
(select * from (SELECT r.id FROM review r WHERE r.book_id = id ORDER BY r.postedAt DESC) where rownum = 1)
这里是否有任何选项可以将 JoinFormula 转换为左连接或类似的东西?
select
book0_.id as id1_0_0_,
book0_.title as title2_0_0_,
book0_.version as version3_0_0_,
(SELECT
r.id
FROM
review r
where
r.book_id = book0_.id
ORDER BY
r.postedAt DESC LIMIT 1) as formula1_0_,
review1_.id as id1_1_1_,
review1_.book_id as book_id4_1_1_,
review1_.comment as comment2_1_1_,
review1_.postedAt as postedAt3_1_1_
from
Book book0_
left outer join
Review review1_
on (
SELECT
r.id
FROM
review r
where
r.book_id = book0_.id
ORDER BY
r.postedAt DESC LIMIT 1
)=review1_.id
where
book0_.id=?
最佳答案
我不确定你要做什么是个好主意。您的领域模型与一本书有很多评论的现实不符。我知道您只想访问最新的评论,但这可能最好作为单独的查询来完成。否则,您可以更新域模型以反射(reflect)现实,但仍然通过 Hibernate 的超惰性属性以高性能方式获取最后的评论。
"Extra-lazy" collection fetching - individual elements of the collection are accessed from the database as needed. Hibernate tries not to fetch the whole collection into memory unless absolutely needed (suitable for very large collections)
@Entity
public class Book {
@OneToMany
@LazyCollection(LazyCollectionOption.EXTRA)
@OrderBy("...")
private List<Review> reviews; //needn't be exposed via public API
public Review getLatestReview(){
return reviews.get(reviews.size() - 1); //or first if ordered desc
}
}
Hibernate 的 @Where
子句也可以用作将集合限制为仅一个元素的替代方法。
关于java - 使用 JPA 和 Hibernate (NotNull) 映射集合的最新子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60011331/