2013-06-26 65 views
14

Tôi biết sử dụng các đối tượng tải/colletions lười biếng bên ngoài phiên, chúng tôi Hibernate.initialize(Object obj) để đối tượng được chuyển làm đối số để khởi tạo() phương pháp được khởi tạo và có thể được sử dụng bên ngoài phạm vi phiên.Làm thế nào Hibernate.initialize() hoạt động

Nhưng những gì tôi không thể hiểu cách hoạt động của tính năng này. Tôi có nghĩa là nếu chúng ta đang làm sau đó chúng tôi kết thúc trong có háo hức lấy như vậy tại sao chúng tôi đã lười biếng trong cấu hình và kết thúc trong tìm nạp háo hức trong khi thời gian chạy.

Nói cách khác, tôi muốn biết sự khác biệt giữa việc sử dụng Hibernate.initialize()eagerly tải đối tượng đó.

Tôi đã nhầm hay bỏ lỡ điều gì đó?

Trả lời

27

Sự khác biệt nằm trong phạm vi áp dụng.

Lý do tạo liên kết tập hợp lười biếng là tránh để nó tải bộ sưu tập mỗi khi đối tượng mẹ được tải nếu bạn không thực sự cần nó.

Nếu bạn đang lười tải một bộ sưu tập bình thường, nhưng để sử dụng cụ thể, bạn cần đảm bảo bộ sưu tập đã được tải trước khi phiên được đóng, bạn có thể sử dụng Hibernate.initialize(Object obj) như bạn đã lưu ý.

Nếu bạn thực tế luôn cần cần bộ sưu tập được tải, bạn thực sự cần tải nó một cách háo hức. Trong hầu hết các phần mềm, đó không phải là trường hợp.

2

Cân nhắc @Don của Ruby trả lời

khác biệt tiếp theo là Hibernate.initialize tạo ra và thực hiện thêm sql cho việc lấy dữ liệu. Vì vậy, bạn có thể sử dụng nó sau khi phiên được đóng lại. Khi bạn sử dụng Eager tìm nạp trong thực thể, nó luôn tìm nạp các bộ sưu tập đó trong quá trình tìm kiếm dữ liệu (trong phiên kết nối) trong cơ sở dữ liệu, nhưng không phải sau khi nó.

1

Thực ra nếu bạn sử dụng EAGER, khi bạn có các bộ sưu tập lớn, nó thực sự ảnh hưởng đến hiệu suất của bạn. Vì vậy, nó là một ý tưởng tốt trong các tình huống như thế này bằng cách sử dụng Hibernate.initialize.

Hãy xem này: Hibernate Lazy Fetch vs Eager Fetch Type

+1

Nếu bạn có một bộ sưu tập sẽ truy cập bên ngoài phiên và bạn chỉ làm Hibernate.initialize bạn sẽ nhận được một LazyInitializationException tốt đẹp khi truy cập một thành viên. –

4

Hãy xem xét ví dụ sau:

Tôi có một thực thể LoanApplication (mà trong trường hợp này là một đối tượng rất nặng) trong đó có các lĩnh vực khác nhau bên trong của nó (mà cũng có thể lớn). Hãy xem xét ví dụ trường SubLoan trong LoanApplication.

@OneToMany(fetch = FetchType.LAZY) 
@JoinColumn(name = "application_fk") 
@Index(name = "appl_fk_idx_subloansLoanApp") 
private Set<SubLoan> subLoans; 

Loại tìm nạp là LAZY trong ví dụ này. Bây giờ nếu trong phương thức của một số bộ điều khiển trong khi thực hiện một số thao tác, bạn gặp LoanApplication, các tập con con sẽ ban đầu là null nếu bạn không muốn sử dụng nó. Trong trường hợp đó bạn sử dụng Hibernate.initialize như sau:

Hibernate.initialize(loanApplication.getSubLoans()); 

Điều này giúp cải thiện hiệu suất chủ yếu bởi vì mỗi lần bạn lấy LoanApplication, tập lớn các đối tượng ví dụ: 'subLoan' sẽ được ban đầu có sản phẩm nào trừ khi bạn thực sự muốn họ.

0

Hãy xem xét bạn có một bảng có thể có quan hệ với 4 bảng khác. Trong trường hợp này nếu bạn sử dụng mong muốn sau đó, tất cả các mối quan hệ tương ứng từ tất cả bốn bảng có liên quan sẽ được tìm nạp trong mọi hoạt động tìm nạp.Nếu bạn cần dữ liệu từ chỉ một bảng trong số các bảng có liên quan, vì vậy trong trường hợp này bạn chỉ có thể tìm nạp mối quan hệ được yêu cầu thay vì vận chuyển toàn bộ bốn dữ liệu của bảng có liên quan bằng cách sử dụng Hibernate.initialize cơ sở.

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