برای این کار می توان یک جدول تاریخچه برای جدول مورد نظر تعریف کرد که از نظر ساختار کاملا شبیه به جدول اصلی است و هر زمانی که رکوردی در جدول اصلی تغییر کرد یک رکورد در جدول تغییرات اضافه می شود که محتوی مقادیر قدیمی است.
Hibernate یک ماژول با نام Envers دارد (از Hibernate 3.5 به بعد) که اینگونه کارها را انجام می دهد و لزومی ندارد خودمان با اجرای یک query جدید (insert) بصورت دستی این عملیات را مدیریت کنیم.
برای استفاده از Envers پس از قرار دادن Maven Dependency در فایل pom:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<version>4.0.1.Final</version>
</dependency>
باید listener های زیر نیر درون فایل hibernate.cfg.xml تعریف شود:
<mapping class="com.javabyab.model.User" />
<listener class="org.hibernate.envers.event.AuditEventListener" type="post-insert"/>
<listener class="org.hibernate.envers.event.AuditEventListener" type="post-update"/>
<listener class="org.hibernate.envers.event.AuditEventListener" type="post-delete"/>
<listener class="org.hibernate.envers.event.AuditEventListener" type="pre-collection-update"/>
<listener class="org.hibernate.envers.event.AuditEventListener" type="pre-collection-remove"/>
<listener class="org.hibernate.envers.event.AuditEventListener" type="post-collection-recreate"/>
در مثال بالا برای فعال سازی ذخیره سازی تاریخچه برای کلاس User باید از انوتیشن های @Audited و @NotAudited استفاده شود:
@Entity
@Audited
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(length = 20)
private String firstName;
@Column(length = 20)
private String lastName;
@Column(length = 20)
@NotAudited
private String password;
پس از اجرای Hibernate علاوه بر جدول user دو جدول با نام های user_aud و revinfo نیز ساخته می شود که تاریخچه تغییرات Entity را درون خود ذخیره می کنند:
select * from user;
+----+-----------+----------+---------------+
| id | firstName | lastName | password |
+----+-----------+----------+---------------+
| 1 | Saeed | Zarinfam_| pass |
+----+-----------+----------+---------------+
select * from user_aud;
+----+-----+---------+-----------+----------+
| id | REV | REVTYPE | firstName | lastName |
+----+-----+---------+-----------+----------+
| 1 | 1 | 0 | Saeed | Zarinfam |
+----+-----+---------+-----------+----------+
select * from revinfo;
+-----+---------------+
| REV | REVTSTMP |
+-----+---------------+
| 1 | 1375956506278|
+-----+---------------+