2012-04-18 45 views
5

Tôi đang cố gắng sử dụng Hibernate để truy xuất khoảng 100 triệu hàng từ một bảng. Tôi có một mục thực thể tồn tại lâu dài chứa một tập hợp các khoản phí bên trong (một thực thể khác tồn tại). Vì tôi sẽ lặp lại kết quả và truy cập phí cho mọi đối tượng, tôi muốn háo hức tìm nạp phí để tránh vấn đề n + 1.Tìm nạp bộ sưu tập trong Hibernate với ScrollableResults

Tôi cũng nên đề cập rằng tôi muốn tham gia nó với một bảng khác được gọi là nhà cung cấp (ánh xạ một-một nhưng không có khóa ngoại). Tôi đã thử:

String query = "select new " + Order.class.getName() 
      + "(i, p) from Item i left join fetch i.fees f, Provider p where " 
      + "p.factoryId=i.factoryId and p.factoryRef=i.factoryRef"; 

return session.createQuery(query).scroll(); 

Lớp đặt hàng của tôi chứa trường Nhà cung cấp và trường Mục. Tôi nhận được lỗi này:

Caused by: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list

Tôi muốn kết thúc bằng danh sách có thể cuộn của Đơn đặt hàng chứa Item (với phí được tìm nạp háo hức) và Nhà cung cấp.

Trả lời

1

Mã này từ SelectClause gây cho bạn những rắc rối:

if (!fromElementsForLoad.contains(origin)) { 
         throw new QueryException(
           "query specified join fetching, but the owner " + 
           "of the fetched association was not present in the select list " + 
           "[" + fromElement.getDisplayText() + "]" 
         ); 

Như bạn có thể thấy, khi các từ khóa lấy được nhắc đến, hibernate kiểm tra để xem nếu bạn yêu cầu phụ huynh lĩnh vực lấy trang trí. fromElementsForLoad.contains(origin)

Họ có thể đã làm điều đó để bảo vệ bạn khỏi việc tham gia dự phòng khiến bạn mất nhiều chi phí về hiệu suất. Đó là một điều tốt vì không có lý do gì để tìm nạp liên kết nếu bạn không bao giờ sử dụng nó.

Tôi tin rằng trong trường hợp của bạn - gói Item.class trong Order.class mới ẩn thực tế là bạn sử dụng phụ huynh trường trang trí tìm nạp trong truy vấn.

Hiện tại tôi không có khả năng gỡ lỗi nên tôi không thể xác thực điều này. thử và gỡ lỗi hàng chính xác này từ SelectClause.class và xem những phần tử nào giữ bộ sưu tập fromElementsForLoad.

Nếu bạn muốn tránh vấn đề n + 1, tôi khuyên bạn nên khởi tạo Order.class sau truy vấn. Bạn chỉ có thể chọn Mục và Nhà cung cấp.

Nếu bạn không thể xác thực điều này, tôi sẽ đến một máy tính phù hợp vào tuần tới và mở rộng câu trả lời của tôi.

+0

Tôi nghĩ câu trả lời này là đúng. Nếu vậy, bạn sẽ có thể cho Hibernate biết rằng bạn đang thực sự tìm nạp 'Item' bằng cách thay đổi truy vấn để trả về 'List' thay vì xây dựng một' Order': 'select i, p from ...'. Sau đó, bạn sẽ phải tạo ra 'Order's bằng tay. –

0

Cố gắng xóa left join fetch i.fees f và thực hiện tìm nạp mong muốn trong ánh xạ.

Các vấn đề liên quan