Tôi đang sử dụng Hibernate Envers để duy trì lịch sử đối tượng. Tại một số điểm, chúng tôi muốn chụp ảnh chụp nhanh trạng thái đồ thị đối tượng - và chúng tôi có thể thực hiện điều này bằng cách biết bản sửa đổi Envers tương ứng mà chúng tôi lưu trữ trên bản ghi kiểm toán.Làm thế nào để buộc Hibernate Envers cam kết sửa đổi trong một phương pháp Spring @Transactional
Tuy nhiên, chúng tôi gặp sự cố. Đối tượng cha được cập nhật trong cùng một giao dịch mà chúng ta tạo và lưu trữ bản ghi kiểm toán con của nó - hoàn thành với bản sửa đổi Envers. Chúng tôi có thể nhận được phiên bản mới nhất:
Number revision = reader.getRevisionNumberForDate(new Date(Long.MAX_VALUE));
hoặc tạo ra một phiên bản mới:
Number revision = reader.getCurrentRevision(DefaultRevisionEntity.class, true).getId();
và sử dụng một trong hai, nhưng cam của cha mẹ luôn luôn xảy ra sau đó. Và đó là khi Envers tăng bản sửa đổi. Do đó bản sửa đổi chúng tôi thực sự cần tham khảo trong hồ sơ kiểm toán luôn cao hơn giá trị được lưu trữ. Trong trường hợp đơn giản nhất, chúng tôi nhận và lưu trữ phiên bản N nhưng phiên bản cha mẹ chúng ta cần được lưu giữ như N + 1.
Các tài liệu tham khảo đọc AuditReader có thể thu được với:
JpaTransactionManager transactionManager; // injected
EntityManagerFactory emf = transactionManager.getEntityManagerFactory();
EntityManager entityManager = emf.createEntityManager();
AuditReader reader = AuditReaderFactory.get(entityManager);
Chúng tôi đang sử dụng Spring 3 Chú thích @Transactional và Hibernate 4.2.
đồ thị dưới lớp tối thiểu:
Parent.class
int version // for hibernate optimistic locking
String revisionName
List<AuditChild> audits
AuditChild.class
int enversRevision // use to retrieve previous graphs of parent
Tôi đã thử nhiều phương pháp để buộc các cam kết của cha mẹ để xảy ra đầu tiên, trong đó có:
- Splitting mã trên nhiều phương pháp với @Transactional (propagation = Propagation.REQUIRES_NEW)
- Yêu cầu rõ ràng về thực thểManager.flush();
Mọi thứ tôi đã thử đều không có hiệu lực hoặc gây ra các sự cố khác. Tôi rất vui khi được nghe về các giải pháp đã làm việc cho người khác. Cảm ơn.
Số sửa đổi phải là duy nhất cho giao dịch, bạn có chắc chắn rằng 'reader.getCurrentRevision (DefaultRevisionEntity.class, true) .getId()' không hoạt động?Bạn cần tham khảo bản sửa đổi "hiện tại" cho giao dịch hiện tại. – adamw
@adamw Có để tạo bản sửa đổi mới. Tuy nhiên khi giao dịch kèm theo của tôi đã được cam kết sửa đổi thực tế trên các hàng cập nhật có liên quan trong * _AUD bảng (s) là> n (n + 1 khi không có bản cập nhật khác để cơ sở dữ liệu chồng chéo lên tx này). Vì vậy, các Id trên đối tượng trả về từ 'getCurrentRevision()' không phải là một áp dụng khi Tx hiện tại đã được cam kết. Công việc của tôi xung quanh là tạo một bản sửa đổi giả (-1) và trong giao dịch thứ 2 để đọc lại và cập nhật tài liệu tham khảo sửa đổi của tôi. (Môi trường: Hibernate Envers 4.2, Spring 3.2 @Transactional các giao dịch được chú thích; DB2 9.1). – user598656
Hmm, tốt nếu bạn gọi getCurrentRevision() trong một TX, bạn sẽ nhận được bản sửa đổi cho giao dịch đó. Bạn có bất kỳ es() es ở giữa? Mặc dù điều đó không quan trọng lắm. – adamw