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.