2010-09-20 24 views
5

Chúng tôi có yêu cầu về dự án của chúng tôi, nơi chúng tôi cần duy trì một loại lịch sử thay đổi được thực hiện cho một số thực thể nhất định trong Ứng dụng. Ứng dụng này là một ứng dụng web Java dựa trên Struts, Spring và Hibernate. Cách tiếp cận nào đã được sử dụng trong trường hợp này?Ghi nhật ký Thay đổi thực thể trong Ứng dụng web Java

  • Trình kích hoạt trên các bảng tương ứng là một ý tưởng nhưng chúng không dễ bảo trì? và có lẽ họ cũng không nên là một phần của giao dịch (ok của nó nếu kích hoạt thất bại, nhưng các giao dịch cập nhật thực thể không nên thất bại).
  • Sử dụng AoP cho điều này vì mối quan tâm chéo của nó, nhưng phải thực sự chi tiết, như chỉ ghi lại các giá trị khi thực thể thay đổi. (Tất cả các chỉnh sửa không có các phương thức khác nhau tương ứng của chúng ... nhiều chỉnh sửa xảy ra trong một Phương thức java đơn).
  • Sử dụng Trình nghe sự kiện Hibernate.

Có phương pháp nào khác để thực hiện loại hoạt động này không?

Trả lời

3

Bởi vì bạn nói

Mọi chỉnh sửa không có phương pháp khác nhau tương ứng của họ ... nhiều chỉnh sửa xảy ra trong một phương pháp java đơn

Thậm chí nếu phương pháp của bạn chỉ nhận một đối số như và bạn có thể truy xuất các mối quan hệ của nó, AOP vẫn có thể là một ý tưởng hay. Tôi mạnh mẽ khuyên bạn thấy điều này nice article

Các tài liệu Hibernate tự nói:

Hibernate Interceptor cho phép các ứng dụng để kiểm tra và/hoặc thao tác thuộc tính của một đối tượng dai dẳng trước khi nó được lưu, cập nhật, xóa hoặc tải . Có thể sử dụng cho việc này để theo dõi thông tin kiểm tra.

Nhưng nó cũng nói

Đảm bảo rằng bạn không lưu trữ quốc gia sessionspecific, vì nhiều phiên sẽ sử dụng đánh chặn này có khả năng đồng thời

Nếu bạn sử dụng một mùa xuân quản lý giao dịch , bạn có thể lấy phiên được nối với Chủ đề hiện tại bằng cách sử dụng sessionFactory.getCurrentSession();

public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { 
    if(entity instanceof SomeEntity) { 
     Session session = sessionFactory.getCurrentSession(); 

Xem getCurrentSession() tài liệu

Nếu không, bạn nên tạo một chặn Hibernate địa phương (gắn vào phiên mở) thay vì một đánh chặn toàn cầu (thuộc SessionFactory), và sau đó, thiết lập của nó phiên

AuditableInterceptor interceptor = new AuditableInterceptor() 
Session session = sessionFactory.openSession(interceptor); 

/** 
    * do it before processing anything if you use local interceptor 
    */ 
interceptor.setSession(session); 

Về trình kích hoạt, tùy thuộc vào các vấn đề khác như quản trị DB (bạn có quyền truy cập quản trị DB. Nếu không, hãy nói với DBA là đặt cược tốt nhất của bạn).

+0

Cảm ơn thông tin Arthur. Để thực hiện đơn giản, tôi đang cố gắng mở rộng Trình nghe sự kiện Hibernate. –

+0

+1, để giải thích mục đích chung. – Bozho

+0

+1 như Bozho đã nói –

4

JBoss Envers hỗ trợ thử giọng và phiên bản - hãy xem.

+0

Thú vị (+1) Bạn có sử dụng thành công không ?? –

+0

@Arhtur - không, than ôi. Nhưng tôi biết những người sử dụng nó và nói nó tốt :) – Bozho

+0

Và +1 quá. Envers có vẻ phù hợp ở đây. –

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