Bạn chỉ có thể sử dụng EntityGraph
nếu thuộc tính liên kết là một phần của lớp cha và thuộc tính đó cũng là một phần của tất cả các lớp con. Nếu không, EntityGraph
sẽ luôn không thành công với Exception
mà bạn hiện đang nhận được.
Cách tốt nhất để tránh vấn đề chọn N + 1 của bạn là chia truy vấn của bạn thành 2 truy vấn:
Truy vấn đầu tiên tìm nạp MCValue
các thực thể sử dụng EntityGraph
để tìm nạp liên kết được ánh xạ bởi selected
thuộc tính. Sau truy vấn đó, các thực thể này sau đó được lưu trữ trong bộ đệm ẩn cấp 1 của Hibernate / ngữ cảnh liên tục. Hibernate sẽ sử dụng chúng khi nó xử lý kết quả của truy vấn thứ 2.
@Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List<MCValue> findAll();
Sau đó, truy vấn thứ 2 tìm nạp Answer
thực thể và sử dụng EntityGraph
cũng để tìm nạp Value
được liên kết các thực thể. Đối với mỗi Value
thực thể, Hibernate sẽ khởi tạo lớp con cụ thể và kiểm tra xem bộ đệm ẩn cấp 1 đã chứa một đối tượng cho tổ hợp khóa chính và lớp đó chưa. Nếu đúng như vậy, Hibernate sử dụng đối tượng từ bộ đệm ẩn cấp 1 thay vì dữ liệu được trả về bởi truy vấn.
@Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List<Answer> findAll();
Bởi vì chúng tôi đã tìm nạp tất cả MCValue
các thực thể có selected
được liên kết các thực thể, bây giờ chúng ta nhận được Answer
các thực thể có giá trị value
được khởi tạo sự kết hợp. Và nếu liên kết chứa MCValue
thực thể, selected
của nó liên kết cũng sẽ được khởi tạo.