2011-03-10 34 views
23

Trong Hibernate Envers, tất cả các bộ sưu tập liên quan của một thực thể được nạp lazily, bất kể loại tìm nạp nào được đặt. Vì vậy, khi kiểm traquerying cho một thực thể có một bộ sưu tập của các thực thể khác (cả hai được kiểm toán, tất nhiên), bộ sưu tập là SetProxy lúc đầu (có thể được nhìn thấy khi gỡ lỗi).Hibernate Envers: Khởi tạo Envers Proxies

Vì vậy, làm cách nào để khởi tạo proxy đó? Sử dụng Hibernate.initialize() không có hiệu lực (Tôi nghi ngờ vì Hibernate và Envers đang sử dụng các đối tượng proxy khác nhau). Tôi biết tôi có thể khởi tạo các thiết lập bằng cách lặp qua các mục của nó, nhưng đó không phải là một lựa chọn cho tôi bởi vì tôi có nhiều bộ sưu tập trong một thực thể và chưa kể đến các vấn đề bảo trì.

Tôi cần khởi tạo chúng một cách háo hức vì tôi đang truy cập bộ sưu tập vào một thời điểm sau đó khi phiên Hibernate đã bị đóng (chuyển đổi đối tượng miền thành dtos).

Tôi đang sử dụng Hibernate 3.5.6.

+0

Tôi không thể làm việc này! Envers dường như bỏ qua kế hoạch tìm nạp! Tôi có một số thực thể thiết lập để tìm nạp háo hức với chế độ tìm nạp SELECT (vì tôi biết chúng luôn ở trong bộ nhớ cache cấp 2 - chỉ đọc và vĩnh cửu).Tôi nhận được lỗi khởi tạo lười biếng khi kết xuất JSP. SƠN TRONG BẠN-BIẾT-GÌ. : (Grrr! – les2

Trả lời

13

Rõ ràng, đây là sự cố mở với Hibernate Envers. Đã có sự cố hiện có trong JIRA của họ: https://hibernate.atlassian.net/browse/HHH-3552. Vui lòng bỏ phiếu cho nó, có thể nó sẽ tăng tốc mọi thứ, khi họ thấy rằng có một số người muốn điều này được sửa;)

Cho đến khi nhóm Envers khắc phục sự cố này, có một công việc xung quanh hoạt động cho tôi : Gọi size() trên bộ sưu tập sẽ khởi tạo các đối tượng proxy.

+1

Hibernate.initialize() không hoạt động cho chúng ta nữa. Chỉ #size() –

-2

Có gì đó không ổn với thiết kế của bạn.

Nếu bạn cần khởi tạo chúng bên trong thiết bị chặn (tôi nghi ngờ Envers hoạt động bằng cách chặn cuộc gọi hibernate), điều đó có nghĩa là bạn cần biết về kiểu miền của bạn trước. Kiểm toán phải là mối quan tâm hoàn toàn độc lập từ mô hình miền. Có điều này cho biết, bạn có thể cuộn trình khởi tạo của riêng mình bằng cách sử dụng một số phương pháp phản chiếu chung để lặp lại bộ sưu tập hoặc bạn có thể sử dụng mẫu Mô hình mở trong phiên và điều chỉnh nó để làm việc với Envers (ví dụ: bên trong đánh chặn của bạn).

Hãy nhớ rằng việc truy cập các mục này có thể sẽ kích hoạt các truy vấn khác, điều này có thể gây nhầm lẫn nếu bạn phân tích nhật ký.


Sửa: Dường như ngủ đông có lấy hồ sơ, có thể cho phép bạn chọn một kế hoạch lấy khi chạy. Xem số SO questiondocs này.

+0

Tôi không chắc chắn những gì bạn có nghĩa là bằng cách "khởi tạo chúng bên trong một interceptor". Sau khi tất cả, tôi nhận được các đối tượng miền như nó được cho là do Envers API (thực hiện một AutitQuery thông qua AuditReader). vấn đề của tôi thực sự là một vấn đề mở (http://opensource.atlassian.com/projects/hibernate/browse/HHH-3552) như tôi đã phát hiện ra sau này –

+0

Có cùng một vấn đề. – ndtreviv

+0

Có một số loại công việc xung quanh Bạn phải gọi 'size()' trên các bộ sưu tập. Các đối tượng proxy Envers sau đó sẽ được khởi tạo –

4

Cách giải quyết tốt nhất mà tôi đã tìm thấy cho đến nay để khởi tạo proxy Envers là sử dụng Dozer. Lập bản đồ thực thể được kiểm toán trả về bởi Envers để chính nó buộc khởi tạo.

Ví dụ:

// Assuming you have an initialized EntityManager in entityManager & 
    // id contains your entity id.. 

    List<Object[]> auditList = (List<Object[]>)AuditReaderFactory. 
            get(entityManager). 
            createQuery(). 
            forRevisionsOfEntity(Foo.class, false, true). 
            add(AuditEntity.id().eq(id)). 
            getResultList(); 

    // Use a singleton in production apps instead... 
    DozerBeanMapper mapper = new DozerBeanMapper(); 

    for(Object[] audit : auditList) { 
     audit[0] = mapper.map(audit[0], Foo.class); 
    } 

    // The proxies in the Foo instances in auditList are now initialized 

Tôi không phải là rất hài lòng với giải pháp này, nhưng tôi thích nó hơn khởi tạo các proxy bằng tay chạm vào các bộ sưu tập. Hy vọng ai đó đến với một lựa chọn tốt hơn hoặc HHH-3552 được cố định!

+0

Giải pháp tốt nhưng xem ra các lỗi gây ra bởi việc không tuân thủ chính xác getter và setter đặt tên cho tất cả các thuộc tính trong tất cả các lớp của toàn bộ đồ thị đối tượng.Một ví dụ lỗi có thể được cho boolean tài sản, ví dụ như http://stackoverflow.com/câu hỏi/532264 8/for-a-boolean-field-cái gì-là-đặt tên-quy ước-cho-nó-getter-setter – user598656

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