2010-05-26 34 views
29

Có cách nào tôi có thể đếm kích cỡ của bộ sưu tập được liên kết mà không khởi tạo không?Kích thước bộ sưu tập đếm ngủ đông mà không cần khởi tạo

ví dụ:

Select count(p.children) from Parent p 

(có một lý do chính đáng tại sao tôi không thể làm theo cách này bất kỳ khác như tôi mệnh đề where là phức tạp hơn và tôi từ khoản là một truy vấn đa hình)

Cảm ơn.

+0

Hãy coi chừng rằng bạn dường như có ít quyền kiểm soát khóa được sử dụng khi thực hiện kiểm tra sự tồn tại có chứa trên LazyCollection. Đó là một chút của một gotcha bởi vì bạn không thể sử dụng các phím tự nhiên để làm kiểm tra sự tồn tại. –

Trả lời

53

Một giải pháp có thể khác với các truy vấn có thể ánh xạ children với lazy="extra" (theo ký hiệu XML). Bằng cách này, bạn có thể tìm nạp Phụ huynh với bất kỳ truy vấn nào bạn cần, sau đó gọi parent.getChildren().size() mà không tải toàn bộ bộ sưu tập (chỉ truy vấn loại SELECT COUNT được thực thi).

Với chú thích, nó sẽ là

@OneToMany 
@org.hibernate.annotations.LazyCollection(
org.hibernate.annotations.LazyCollectionOption.EXTRA 
) 
private Set<Child> children = new HashSet<Child>(); 

Cập nhật: Trích từ Java Persistence with Hibernate, ch. 13.1.3:

Một proxy được khởi tạo nếu bạn gọi bất kỳ phương pháp đó không phải là phương pháp nhận dạng getter , một bộ sưu tập được khởi tạo nếu bạn bắt đầu lặp lại thông qua các yếu tố của nó hoặc nếu bạn gọi bất kỳ của bộ sưu tập quản lý hoạt động, chẳng hạn như size() và . Hibernate cung cấp một cài đặt bổ sung hữu ích cho các bộ sưu tập lớn; chúng có thể được lập bản đồ dưới dạng thêm lười biếng. [...]

[Ánh xạ như trên,] bộ sưu tập không còn được khởi tạo nếu bạn gọi size(), hoặc isEmpty() - cơ sở dữ liệu được truy vấn để truy xuất thông tin cần thiết. Nếu đó là Map hoặc List, hoạt động containsKey()get() cũng truy vấn cơ sở dữ liệu trực tiếp.

Vì vậy, với một thực thể ánh xạ như trên, sau đó bạn có thể làm

Parent p = // execute query to load desired parent 
// due to lazy loading, at this point p.children is a proxy object 
int count = p.getChildren().size(); // the collection is not loaded, only its size 
+0

bạn có thể xây dựng thêm một chút về điều này không. –

+1

@Varun, xem cập nhật của tôi. –

+2

Cảnh giác, có lỗi: https://hibernate.atlassian.net/browse/HHH-9227 –

1

Bạn có thể sử dụng phiên # createFilter đó là một hình thức của HQL đó một cách rõ ràng hoạt động trên các bộ sưu tập. Ví dụ, bạn đề cập đến cha mẹ và trẻ em vì vậy nếu bạn có một người p hình thức cơ bản nhất sẽ là:

session.createFilter(p.getChildren(), "").list() 

Điều này chỉ đơn giản trả về cho bạn một danh sách các trẻ em. Điều quan trọng cần lưu ý là bộ sưu tập được trả về không phải là "sống", nó không có bất kỳ cách nào liên kết với p.

Phần thú vị đến từ đối số thứ hai. Đây là một đoạn HQL. Ở đây ví dụ, bạn có thể muốn:

session.createFilter(p.getChildren(), "select count(*)").uniqueResult(); 

Bạn nói bạn có một mệnh đề where, vì vậy bạn cũng có thể muốn:

session.createFilter(p.getChildren(), "select count(*) where this.age > 18").uniqueResult(); 

Thông báo không có là từ khoản. Đó là để nói rằng mệnh đề từ được ngụ ý từ hiệp hội.Các phần tử của bộ sưu tập được đưa ra bí danh 'this' để bạn có thể tham khảo nó từ các phần khác của đoạn HQL.

-2

Bạn có thể làm điều tương tự như thế này:

@Override 
public FaqQuestions getFaqQuestionById(Long questionId) { 
    session = sessionFactory.openSession(); 
    tx = session.beginTransaction(); 
    FaqQuestions faqQuestions = null; 
    try { 
     faqQuestions = (FaqQuestions) session.get(FaqQuestions.class, 
       questionId); 
     Hibernate.initialize(faqQuestions.getFaqAnswers()); 

     tx.commit(); 
     faqQuestions.getFaqAnswers().size(); 
    } finally { 
     session.close(); 
    } 
    return faqQuestions; 
} 

Chỉ cần sử dụng faqQuestions.getFaqAnswers() kích thước() nin điều khiển của bạn và bạn sẽ nhận được kích thước nếu lười biếng intialised danh sách, mà không cần lấy danh sách riêng của mình..

+1

Chính xác điều gì xảy ra ở đây và tại sao điều này sẽ hoạt động? Tại sao giao dịch? – h22

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