Vấn đề là tôi có hai túi trong thực thể của mình mà tôi muốn hiển thị trong giao diện jsf của tôi (Mùa xuân ở phía sau để không tải xuống). Vì vậy, tôi phải háo hức lấy chúng để hiển thị các thông tin trong một danh sách như thế này:Hibernate fetch join -> không thể tìm nạp nhiều túi
- điểm 1 (Label 1, Label 2) (Tag1 ... Tag n)
- điểm 2 (Label 3, Label 4) (Tag1 ... Thẻ n)
Đặt cả hai danh sách vào trạng thái mong muốn không hoạt động. Vì vậy, tôi đã thử vận may của mình bằng cách tìm nạp. Nó cho phép tôi lấy một danh sách, nhưng khi tôi thêm vào danh sách thứ hai tôi nhận được lỗi "không thể tìm nạp nhiều túi" đã biết.
Hibernate có thể xử lý hai lần tìm nạp trong một truy vấn không?
public class PointOfInterest
@OneToMany(mappedBy="poi")
private List<PointOfInterestLabel> labels = new ArrayList<PointOfInterestLabel>();
@ManyToMany
private List<Tag> tags = new ArrayList<Tag>();
tôi lấy tham gia:
SELECT DISTINCT p from PointOfInterest p
left join fetch p.labels
left join fetch p.tags WHERE p.figure = :figure
On khởi động việc tạo ra các nhà máy ngủ đông của tôi không thành công với:
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:94)
at org.hibernate.loader.hql.QueryLoader.<init>(QueryLoader.java:123)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:98)
at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:557)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:422)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883)
... 55 more
Cảm ơn! Đối với thời điểm này tôi thay thế nó bằng Set, nhưng tôi nghĩ rằng tôi sẽ cấu trúc lại giao diện vào ngày mai và hiển thị ít thông tin hơn. Cảm ơn vì bạn đã phản hồi! Làm thế nào bạn sẽ giải quyết nó khi bạn không có phạm vi kiên trì trong lối vào của bạn. Sử dụng các đối tượng truyền dữ liệu được xây dựng trong DAO thay vì các thực thể được tìm nạp? Tôi thừa kế dự án và tôi không được phép thực hiện những thay đổi lớn về thiết kế, cũng như tôi không được phép chuyển đổi nó sang j2ee. : -/ – mkuff
Bạn có thể tắt tải chậm, điều này không tốt cho hiệu suất. Điều này lấy các túi ngay lập tức bằng các truy vấn riêng biệt. Bạn cũng có thể truy cập vào các túi (ví dụ như kích thước) để buộc tải. Các giải pháp hoàn hảo là tạo ra các phiên bên ngoài dao và giữ nó cho một giao dịch kinh doanh toàn bộ. (Tạo một phiên trong mỗi cuộc gọi đến dao được gọi là session-per-call và là một anti-pattern.) –
Vì vậy, đây thực sự là một vấn đề bắt 22: nếu bạn không sử dụng tham gia tìm nạp, bạn nhận được vấn đề n + 1 hoặc ngoại lệ khởi tạo lười biếng. Phiên bên ngoài dao là một hack, trước hết bởi vì nó không nằm gần hợp đồng JPA và thứ hai vì nó không thể kiểm soát được, vì bạn không nên đưa ra bất kỳ giả định nào về tuổi thọ của thực thể tại thời điểm bạn tạo nó. Nó có thể trải qua một số yêu cầu, không nhất thiết phải http. – Deroude