2011-08-25 20 views
16

Đây là hoàn cảnh của tôi, tôi có hai cơ bản POJO của mà tôi đã đưa ra một bản đồ ngủ đông đơn giản:thực thể Hibernate Native SQL Query lấy và bộ sưu tập

Person 
    - PersonId 
    - Name 
    - Books 

Book 
    - Code 
    - Description 

My SQL Query trả hàng mà trông như thế này:

PERSONID NAME  CODE DESCRIPTION 
-------- ---------- ---- ----------- 
1  BEN  1234 BOOK 1 
1  BEN  5678 BOOK 2 
2  JOHN  9012 BOOK 3 

truy vấn ngủ đông của tôi trông như thế này:

session.createSQLQuery("select personid, name, code, description from person_books") 
     .addEntity("person", Person.class) 
     .addJoin("book", "person.books") 
     .list(); 

Đây là mỗi phần: 18.1.3 của tài liệu Hibernate: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/querysql.html#d0e17464

Những gì tôi mong đợi để nhận được trong danh sách của tôi là 2 người Objects với các đối tượng cuốn sách chứa đựng trong các bộ sưu tập sách:

List 
|- Ben 
| |- Book 1 
| '- Book 2 
'- John 
    '- Book 3 

Những gì tôi đang thực sự nhìn thấy là thế này:

List 
|- Object[] 
| |- Ben 
| | |- Book 1 
| | '- Book 2 
| '- Book 1 
|- Object[] 
| |- Ben 
| | |- Book 1 
| | '- Book 2 
| '- Book 2 
'- Object[] 
    |- John 
    | '- Book 3 
    '- Book 3 

có ai biết nếu nó có thể để có được những gì tôi muốn sử dụng phương pháp này?

Trả lời

1

Truy vấn của bạn có nên nằm trên bảng người thay vì person_books không?

session.createSQLQuery("select * from person") 
    .addEntity("person", Person.class) 
    .addJoin("book", "person.books") 
    .list(); 
+0

Tôi đã đơn giản hóa ví dụ này vì lợi ích của việc súc tích. Trong việc sử dụng thực tế của tôi "person_books" là một truy vấn phức tạp, hibernate không có cách nào để lấy thông tin cho một "cuốn sách" mà không có tôi cung cấp nó trong truy vấn. Tôi đang lấy một số lượng lớn các hàng cho Người và không muốn thực hiện một truy vấn bổ sung để tìm Sách cho mọi Người. Nếu tôi không thể tìm thấy một giải pháp, tôi có thể sẽ sử dụng phương pháp này nhưng chỉ bỏ qua các hàng mà người đó không thay đổi. – Ben

12

Các công trình sau đây cho tôi:

session.createSQLQuery("select p.*, b.* from person p, book b where <complicated join>"). 
.addEntity("person", Person.class).addJoin("book", "person.books").list(); 

này trả về một Object[] chứa danh sách các Person, mỗi trong số đó có chứa một danh sách các Book s. Nó thực hiện điều này trong một lựa chọn SQL duy nhất. Tôi nghĩ rằng vấn đề của bạn là bạn không cụ thể bí danh người với bất cứ điều gì.

EDIT: Phương thức trả về một đối tượng [], nhưng mảng được điền bằng cá thể Person và chỉ các cá thể Person.

Nếu Hibernate không hiểu cách ánh xạ tới lớp học của bạn hoặc nếu nó không thể hiểu cách ánh xạ tham gia, nó sẽ trả về danh sách các đối tượng. Đảm bảo bạn chỉ có một kết hợp Person/Book trên mỗi dòng.

+0

Điều tôi mong đợi là một danh sách Người, không phải là danh sách đối tượng [] với những người trùng lặp, khi họ sở hữu nhiều hơn một cuốn sách. Xem câu trả lời của tôi cho liên kết đến báo cáo lỗi jiranate hibernate. – Ben

+0

Xin lỗi, để làm cho bản thân mình rõ ràng, phương thức trả về một đối tượng [], nhưng mảng được điền với Person và chỉ Person. Tôi không có bất kỳ cuốn sách nào trong đó. –

1

AFAIK, không thể lấy đối tượng "đã hợp nhất" trở lại từ truy vấn SQL. Bạn sẽ lấy lại chỉ một mảng đối tượng. Những gì tôi đã làm trong tình huống này là tôi đã tạo ra một hàm tạo mới cho thực thể được hợp nhất của tôi, lấy một mảng các đối tượng làm đối số của nó. Sau đó, tôi xây dựng bằng tay.

33

Mở rộng câu trả lời cho Mathews. Buộc hibernate để chỉ trả về một danh sách những người làm:

List<Person> peopleWithBooks = session.createSQLQuery(
    "select {p.*}, {b.*} from person p, book b where <complicated join>"). 
    .addEntity("p", Person.class) 
    .addJoin("b", "p.books") 
    .addEntity("p", Person.class) 
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 
    .list(); 

tổ chức Associated Sách sẽ được lấy và khởi tạo mà không có một cuộc gọi bổ sung cho các db.

Các trùng lặp

.addEntity("p", Person.class) 

là cần thiết vì

.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 

hoạt động trên thực thể cuối cùng nói thêm.

+1

Việc này sẽ tìm nạp mọi thứ cho Người và Sách. Điều gì sẽ xảy ra nếu bạn muốn chỉ chọn một số thuộc tính nhất định để cải thiện hiệu suất. Vì tôi hiểu bất cứ điều gì khác hơn là * hoặc p. * Không hoạt động. – T3rm1

+1

Sử dụng '{p. *}, {B. *}' Cũng sửa thêm một vấn đề chọn lựa bổ sung cho 'sách'. –

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