hibernate学习 hibernate-tutorials(四)——envers

来源:互联网 发布:ubuntu接口配置ip地址 编辑:程序博客网 时间:2024/05/18 00:10

Hibernate Envers目的是根据对实体的设置,提供记录执行数据变更历史的功能(数据变更版本)。它实现原理是通过对Hibernate的操作事件监听并根据基于Annoatation的配置来记录修改数据的内容。


比较entitymanager项目的异同。

主要是实体bean上增加一个@Audited注解。

package org.hibernate.tutorial.envers;import java.util.Date;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;import org.hibernate.annotations.GenericGenerator;import org.hibernate.envers.Audited;@Entity@Table( name = "EVENTS" )@Audited  // <--- this tell Envers to audit (track changes to) this entitypublic class Event {


查看版本的方法如下:

public class EnversIllustrationTest extends TestCase {private EntityManagerFactory entityManagerFactory;@Overrideprotected void setUp() throws Exception {// like discussed with regards to SessionFactory, an EntityManagerFactory is set up once for an application// IMPORTANT: notice how the name here matches the name we gave the persistence-unit in persistence.xml!entityManagerFactory = Persistence.createEntityManagerFactory( "org.hibernate.tutorial.envers" );}@Overrideprotected void tearDown() throws Exception {entityManagerFactory.close();}public void testBasicUsage() {// create a couple of eventsEntityManager entityManager = entityManagerFactory.createEntityManager();entityManager.getTransaction().begin();entityManager.persist( new Event( "Our very first event!", new Date() ) );entityManager.persist( new Event( "A follow up event", new Date() ) );entityManager.getTransaction().commit();entityManager.close();// now lets pull events from the database and list thementityManager = entityManagerFactory.createEntityManager();entityManager.getTransaction().begin();        List<Event> result = entityManager.createQuery( "from Event", Event.class ).getResultList();for ( Event event : result ) {System.out.println( "Event (" + event.getDate() + ") : " + event.getTitle() );}        entityManager.getTransaction().commit();        entityManager.close();// so far the code is the same as we have seen in previous tutorials.  Now lets leverage Envers...// first lets create some revisionsentityManager = entityManagerFactory.createEntityManager();entityManager.getTransaction().begin();Event myEvent = entityManager.find( Event.class, 2L ); // we are using the increment generator, so we know 2 is a valid idmyEvent.setDate( new Date() );myEvent.setTitle( myEvent.getTitle() + " (rescheduled)" );        entityManager.getTransaction().commit();        entityManager.close();// and then use an AuditReader to look back through historyentityManager = entityManagerFactory.createEntityManager();entityManager.getTransaction().begin();myEvent = entityManager.find( Event.class, 2L );assertEquals( "A follow up event (rescheduled)", myEvent.getTitle() );AuditReader reader = AuditReaderFactory.get( entityManager );Event firstRevision = reader.find( Event.class, 2L, 1 );assertFalse( firstRevision.getTitle().equals( myEvent.getTitle() ) );assertFalse( firstRevision.getDate().equals( myEvent.getDate() ) );Event secondRevision = reader.find( Event.class, 2L, 2 );assertTrue( secondRevision.getTitle().equals( myEvent.getTitle() ) );assertTrue( secondRevision.getDate().equals( myEvent.getDate() ) );entityManager.getTransaction().commit();        entityManager.close();}}

运行结果如下:

------------------------------------------------------- T E S T S-------------------------------------------------------Running org.hibernate.tutorial.envers.EnversIllustrationTest七月 16, 2016 8:04:54 下午 org.hibernate.ejb.HibernatePersistence logDeprecationWARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.七月 16, 2016 8:04:54 下午 org.hibernate.ejb.HibernatePersistence logDeprecationWARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.七月 16, 2016 8:04:54 下午 org.hibernate.ejb.HibernatePersistence logDeprecationWARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.七月 16, 2016 8:04:55 下午 org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformationINFO: HHH000204: Processing PersistenceUnitInfo [name: org.hibernate.tutorial.envers...]七月 16, 2016 8:04:55 下午 org.hibernate.Version logVersionINFO: HHH000412: Hibernate Core {4.3.11.Final}七月 16, 2016 8:04:55 下午 org.hibernate.cfg.Environment <clinit>INFO: HHH000206: hibernate.properties not found七月 16, 2016 8:04:55 下午 org.hibernate.cfg.Environment buildBytecodeProviderINFO: HHH000021: Bytecode provider name : javassist七月 16, 2016 8:04:55 下午 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final}七月 16, 2016 8:04:55 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configureWARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)七月 16, 2016 8:04:55 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreatorINFO: HHH000401: using driver [org.h2.Driver] at URL [jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE]七月 16, 2016 8:04:55 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreatorINFO: HHH000046: Connection properties: {user=sa}七月 16, 2016 8:04:55 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreatorINFO: HHH000006: Autocommit mode: false七月 16, 2016 8:04:55 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configureINFO: HHH000115: Hibernate connection pool size: 20 (min=1)七月 16, 2016 8:04:55 下午 org.hibernate.dialect.Dialect <init>INFO: HHH000400: Using dialect: org.hibernate.dialect.H2Dialect七月 16, 2016 8:04:55 下午 org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreationINFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4七月 16, 2016 8:04:56 下午 org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>INFO: HHH000397: Using ASTQueryTranslatorFactory七月 16, 2016 8:04:57 下午 org.hibernate.tool.hbm2ddl.SchemaExport executeINFO: HHH000227: Running hbm2ddl schema exportHibernate: drop table EVENTS if existsHibernate: drop table EVENTS_AUD if existsHibernate: drop table REVINFO if existsHibernate: create table EVENTS (id bigint not null, EVENT_DATE timestamp, title varchar(255), primary key (id))Hibernate: create table EVENTS_AUD (id bigint not null, REV integer not null, REVTYPE tinyint, EVENT_DATE timestamp, title varchar(255), primary key (id, REV))Hibernate: create table REVINFO (REV integer generated by default as identity, REVTSTMP bigint, primary key (REV))Hibernate: alter table EVENTS_AUD add constraint FK_3hegaqrrpmx0jj0c8qacjtira foreign key (REV) references REVINFO七月 16, 2016 8:04:57 下午 org.hibernate.tool.hbm2ddl.SchemaExport executeINFO: HHH000230: Schema export completeHibernate: select max(id) from EVENTSHibernate: insert into EVENTS (EVENT_DATE, title, id) values (?, ?, ?)Hibernate: insert into EVENTS (EVENT_DATE, title, id) values (?, ?, ?)Hibernate: insert into REVINFO (REV, REVTSTMP) values (null, ?)Hibernate: insert into EVENTS_AUD (REVTYPE, EVENT_DATE, title, id, REV) values (?, ?, ?, ?, ?)Hibernate: insert into EVENTS_AUD (REVTYPE, EVENT_DATE, title, id, REV) values (?, ?, ?, ?, ?)Hibernate: select event0_.id as id1_0_, event0_.EVENT_DATE as EVENT_DA2_0_, event0_.title as title3_0_ from EVENTS event0_Event (2016-07-16 20:04:57.655) : Our very first event!Event (2016-07-16 20:04:57.671) : A follow up eventHibernate: select event0_.id as id1_0_0_, event0_.EVENT_DATE as EVENT_DA2_0_0_, event0_.title as title3_0_0_ from EVENTS event0_ where event0_.id=?Hibernate: update EVENTS set EVENT_DATE=?, title=? where id=?Hibernate: insert into REVINFO (REV, REVTSTMP) values (null, ?)Hibernate: insert into EVENTS_AUD (REVTYPE, EVENT_DATE, title, id, REV) values (?, ?, ?, ?, ?)Hibernate: select event0_.id as id1_0_0_, event0_.EVENT_DATE as EVENT_DA2_0_0_, event0_.title as title3_0_0_ from EVENTS event0_ where event0_.id=?Hibernate: select event_aud0_.id as id1_1_, event_aud0_.REV as REV2_1_, event_aud0_.REVTYPE as REVTYPE3_1_, event_aud0_.EVENT_DATE as EVENT_DA4_1_, event_aud0_.title as title5_1_ from EVENTS_AUD event_aud0_ where event_aud0_.REV=(select max(event_aud1_.REV) from EVENTS_AUD event_aud1_ where event_aud1_.REV<=? and event_aud0_.id=event_aud1_.id) and event_aud0_.REVTYPE<>? and event_aud0_.id=?Hibernate: select event_aud0_.id as id1_1_, event_aud0_.REV as REV2_1_, event_aud0_.REVTYPE as REVTYPE3_1_, event_aud0_.EVENT_DATE as EVENT_DA4_1_, event_aud0_.title as title5_1_ from EVENTS_AUD event_aud0_ where event_aud0_.REV=(select max(event_aud1_.REV) from EVENTS_AUD event_aud1_ where event_aud1_.REV<=? and event_aud0_.id=event_aud1_.id) and event_aud0_.REVTYPE<>? and event_aud0_.id=?七月 16, 2016 8:04:57 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stopINFO: HHH000030: Cleaning up connection pool [jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE]Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.112 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

项目源码参考(readme文件有相关测试运行的命令):

 git@code.csdn.net:xiaozaq/hibernate-tutorials.git



0 0