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

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 entity
public class Event {


查看版本的方法如下:

public class EnversIllustrationTest extends TestCase {
	private EntityManagerFactory entityManagerFactory;

	@Override
	protected 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" );
	}

	@Override
	protected void tearDown() throws Exception {
		entityManagerFactory.close();
	}

	public void testBasicUsage() {
		// create a couple of events
		EntityManager 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 them
		entityManager = 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 revisions
		entityManager = 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 id
		myEvent.setDate( new Date() );
		myEvent.setTitle( myEvent.getTitle() + " (rescheduled)" );
        entityManager.getTransaction().commit();
        entityManager.close();

		// and then use an AuditReader to look back through history
		entityManager = 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 logDeprecation
WARN: 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 logDeprecation
WARN: 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 logDeprecation
WARN: 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 logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
	name: org.hibernate.tutorial.envers
	...]
七月 16, 2016 8:04:55 下午 org.hibernate.Version logVersion
INFO: 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 buildBytecodeProvider
INFO: 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 configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
七月 16, 2016 8:04:55 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: 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 buildCreator
INFO: HHH000046: Connection properties: {user=sa}
七月 16, 2016 8:04:55 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
七月 16, 2016 8:04:55 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: 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 useContextualLobCreation
INFO: 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 execute
INFO: HHH000227: Running hbm2ddl schema export
Hibernate: drop table EVENTS if exists
Hibernate: drop table EVENTS_AUD if exists
Hibernate: drop table REVINFO if exists
Hibernate: 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 execute
INFO: HHH000230: Schema export complete
Hibernate: select max(id) from EVENTS
Hibernate: 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 event
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: 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 stop
INFO: 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 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

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

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值