Envers + Seam + JBoss: Why to use?

32

Transcript of Envers + Seam + JBoss: Why to use?

Envers + Seam + JBoss: Why

to use?

Diogo Souza

Envers + Seam + JBoss:

Why to use?

Better...

The handshake

Diogo Souza

Systems Analyst at Indra Company

http://3adiX.com.br

http://diogosouza.com.br

@diogo_souza_c

Ah, the Envers!

Once upon a time, in 2009…

What they say about…

“The Envers project aims to enable

easy auditing/versioning of persistent

classes […]”

Ref: http://www.jboss.org/envers

What they say about…

“[…] All that you have to do is

annotate your persistent class or

some of its properties, that you want

to audit, with @Audited. […]”

Ref: http://www.jboss.org/envers

What they say about…

“[…] For each audited entity, a table

will be created, which will hold the

history of changes made to the

entity. […]”

Ref: http://www.jboss.org/envers

And the best part…

“[…] You can then retrieve and query

historical data without much effort.”

Ref: http://www.jboss.org/envers

http://www.deviantart.com

Some features:

Auditing of all mappings defined by

the JPA specification

Auditing of some Hibernate

mappings, which extend JPA

Logging data for each revision using

a "revision entity"

Querying historical data

Ref: http://www.jboss.org/envers

http://www.deviantart.com

Basically

Each transaction...

...One revision

INSERT

UPDATE

DELETE

Where to use?

Wherever you have Hibernate!

Standalone

JBoss AS

Spring

And how do we use in the past?<property name="hibernate.ejb.event.post-insert"

value="org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener" />

<property name="hibernate.ejb.event.post-update"value="org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener" />

<property name="hibernate.ejb.event.post-delete"value="org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener" />

<property name="hibernate.ejb.event.pre-collection-update"value="org.hibernate.envers.event.AuditEventListener" />

<property name="hibernate.ejb.event.pre-collection-remove"value="org.hibernate.envers.event.AuditEventListener" />

<property name="hibernate.ejb.event.post-collection-recreate"value="org.hibernate.envers.event.AuditEventListener" />

In persistence.xml or hibernate.cfg.xml

And how to use?

<!-- Add on classpath | Maven --><dependency>

<groupId>org.hibernate</groupId><artifactId>hibernate-envers</artifactId><version>4.x.Final</version>

</dependency>

Requirements:

Hibernate 3+

Hibernate annotations

Simple sample

@Entitypublic class Adress {

@Id@GeneratedValueprivate int id;

@Auditedprivate String streetName;

@Auditedprivate Long zipCode;

@Audited@ManyToOneprivate State state;

}

The whole entity

@Auditedpublic class Adress {

@Id@GeneratedValueprivate int id;

private String streetName;

private Long zipCode;

@ManyToOneprivate State state;

}

@Audited // Here too!public class State {

@Id@GeneratedValueprivate int id;

private String stateName;

private Long population;}

… without a field

@Auditedpublic class Adress {

@Id@GeneratedValueprivate int id;

@NotAuditedprivate String streetName;

private Long zipCode;

@ManyToOneprivate State state;

}

Changing the entity table

name@Audited@AuditTable(“TB_ADRESS_AUDIT”)public class Adress {

@Id@GeneratedValueprivate int id;

@NotAuditedprivate String streetName;

private Long zipCode;

@ManyToOneprivate State state;

}

The database

0 ADD

1 MOD

3 DEL

The revision

date!

Querying for entities of a

class at a given revision

AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(MyEntity.class,

revisionNumber);

Querying for revisions, at

which entities of a given class

changed

AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(MyEntity.class,

false, true);

Querying for revisions

between revision dates

AuditReader auditReader = AuditReaderFactory.get(entityManager);

AuditQuery query = auditReader.createQuery().forRevisionsOfEntity(Punishment.class, false, true)

.add(AuditEntity.revisionProperty("timestamp")

.gt(timeStamp).lt(otherTimeStamp)

.add(AuditEntity.revisionType().eq(RevisionType.ADD));

List<Object[]> revisions = query.getResultList();

Configuration Properties// Prefixes and suffixes

org.hibernate.envers.audit_table_prefix

org.hibernate.envers.audit_table_suffix

// Revision number and revision type fields

org.hibernate.envers.revision_field_name

org.hibernate.envers.revision_type_field_name

// Default schema used

org.hibernate.envers.default_schema

Demo Time!

I am not responsible for

any increases in the

number of Brazilian

punishments...

The guy!

Adam Warski

Ref: http://www.warski.org/blog/about/

http://warski.org

Good things!

Easy!

Data as always!

Database schema

doesn’t change

Minimal code changes

Integration with

Hibernate/Red Hat

related

Not so good things!

Dependency of

Hibernate.

Not compatible with

Hibernate-XML-Age.

Extra table for each

table.

Story Time!

References/Links

www.jboss.org/envers

http://docs.jboss.org/envers/docs/

http://www.warski.org/blog/

Thanks!