我有一個簡單的餐廳物體,它有一個投票串列(為了簡潔,省略了一些欄位和方法)。
public class Restaurant extends AbstractNamedEntity {
@OneToMany(mappedBy = "restaurant", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonManagedReference
@Fetch(FetchMode.SUBSELECT)
private List<Vote> votes;
}
這里是關系的另一面
public class Vote extends AbstractBaseEntity {
private Restaurant餐廳。
}
當我嘗試使用Spring data JPA findAll()方法獲取資料,然后將其轉換為DTOs時
public static RestaurantResponseDTO toRestaurantDto(Restaurant) {
return new RestaurantResponseDTO( restaurant.getId(), restaurant.getName(),
restaurant.getAddress(), getRestaurantVoteCount(restaurant))。
}
public static long getRestaurantVoteCount(餐廳) {
var votes = restaurant.getVotes()。
if (votes == null) return 0;
return votes.stream().filter(vote -> vote.getVoteDate().equals(LocalDate.now()) ).count()。
}
這些是我的SQL陳述句:
Hibernate:
選擇
restaurant0_.id作為id1_1_。
restaurant0_.name作為name2_1_。
restaurant0_.address as address3_1_.
從
restaurant0_餐廳
Hibernate。
選擇
votes0_.restaurant_id作為 restaura3_4_1_。
votes0_.id作為id1_4_1_。
votes0_.id作為id1_4_0_。
votes0_.restaurant_id作為 restaura3_4_0_。
votes0_.user_id為user_id4_4_0_。
votes0_.vote_date作為vote_dat2_4_0_。
從
票數 votes0_
其中
votes0_.restaurant_id in (
選擇
restaurant0_.id
從
restaurant0_的id
)
我以為Subselect只需要1個,為什么我有2個呢?
uj5u.com熱心網友回復:
實際上,你看到的是預期的hibernate行為。參見本節的hibernate檔案。
Hibernate將通過生成一個單一的SQL陳述句來初始化所有Restaurant物體的所有votes集合來避免N 1查詢的問題。Hibernate沒有使用傳遞所有的物體識別符號,而是簡單地重新運行之前獲取Restaurant物體的查詢。
P.S. 至于FetchMode.JOIN選項,請注意,正如這里提到的:
我們之所以不使用JPQL查詢來獲取多個部門物體,是因為
FetchMode.JOIN策略將被查詢獲取指令所覆寫。要使用JPQL查詢獲取多個關系,必須使用
JOIN FETCH指令來代替。
所以,我想對于你的情況,最靈活的方法是寫自己的JPQL查詢,并在需要的地方使用JOIN FETCH指令。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/309848.html
標籤:
