Đây thực sự là hành vi mong đợi nếu tôi hiểu chính xác cấu hình của bạn.
Hibernate không không trả về kết quả riêng biệt cho truy vấn có tìm nạp tham gia bên ngoài được bật cho bộ sưu tập (ngay cả khi tôi sử dụng từ khóa riêng biệt)? Đầu tiên, bạn cần hiểu SQL và cách OUTER JOINs làm việc trong SQL. Nếu bạn không hoàn toàn hiểu và hiểu được các kết nối bên ngoài trong SQL, không tiếp tục đọc mục Câu hỏi thường gặp này nhưng tham khảo hướng dẫn sử dụng SQL hoặc hướng dẫn . Nếu không, bạn sẽ không hiểu giải thích sau đây và bạn sẽ phàn nàn về hành vi này trên diễn đàn Hibernate.
ví dụ điển hình có thể quay trở lại tài liệu tham khảo bản sao của cùng một đối tượng thứ tự:
List result = session.createCriteria(Order.class)
.setFetchMode("lineItems", FetchMode.JOIN)
.list();
<class name="Order">
...
<set name="lineItems" fetch="join">
List result = session.createCriteria(Order.class)
.list();
List result = session.createQuery("select o from Order o left join fetch o.lineItems").list();
Tất cả những ví dụ tạo ra câu lệnh SQL giống nhau:
SELECT o.*, l.* from ORDER o LEFT OUTER JOIN LINE_ITEMS l ON o.ID = l.ORDER_ID
Bạn muốn biết lý do tại sao các bản sao có ở đó?Hãy xem kết quả SQL, Hibernate không ẩn các phần tử trùng lặp này ở bên trái của kết quả được kết hợp bên ngoài nhưng trả về tất cả các bản sao của bảng điều khiển. Nếu bạn có 5 đơn đặt hàng trong cơ sở dữ liệu và mỗi đơn đặt hàng có 3 chi tiết đơn hàng, kết quả sẽ là 15 hàng. Danh sách kết quả Java của các truy vấn này sẽ có 15 phần tử, tất cả các loại Thứ tự. Chỉ có 5 trường hợp đặt hàng sẽ được tạo bởi Hibernate, nhưng các bản sao của kết quả SQL là được giữ nguyên dưới dạng tham chiếu trùng lặp với 5 trường hợp này. Nếu bạn không hiểu câu cuối cùng này, bạn cần phải đọc trên Java và sự khác biệt giữa một thể hiện trên vùng heap Java và tham chiếu đến ví dụ như vậy.
(Tại sao phải tham gia bên ngoài bên trái? Nếu bạn có một đơn hàng bổ sung không có dòng mục, tập hợp kết quả sẽ là 16 hàng với NULL điền bên phải bên, nơi dữ liệu chi tiết đơn hàng Bạn muốn đặt hàng ngay cả khi họ không có chi tiết đơn hàng, phải không? Nếu không, hãy sử dụng kết nối bên trong tìm nạp trong HQL của bạn).
Hibernate không lọc ra các tham chiếu trùng lặp này theo mặc định. Một số người (không phải bạn) thực sự muốn điều này. Làm thế nào bạn có thể lọc chúng ra?
Như thế này:
Collection result = new LinkedHashSet(session.create*(...).list());
Bạn đã thử bật show_sql để xem điều gì đang xảy ra bên dưới? –
Vui lòng thêm mã lớp OrderTransaction và Order. \ –