Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level...

25
Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220

Transcript of Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level...

Page 1: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

Hibernate EnversEasy Entity Auditing

Adam WarskiLevel N Consulting6220

Page 2: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

2

Example: Person & Address

> We want to store the history of a Person's Addresses

Page 3: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

3

What is Envers?

> An entity versioning/auditing library

> Part of Hibernate

> Simplifies storing and retrieving historical data

Page 4: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

4

Assumptions> Transparent

– „Current” data can be used as always (queried, persisted, etc.)

> Not intrusive– The database schema isn't changed (some tables can be added)– Minimal code changes

> Slowly changing data

Page 5: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

5

How does Envers work?

> The programmer specifies which Entities should be audited

> For each audited entity, an audit entity is (dynamically) created

> e.g. entity „Address” has an „Address_AUD” companion

> The companion stores historical data

Page 6: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

6

How does Envers work?

> On an update/insert/delete: data inserted to audit tables

> All changes in a transaction: 1 revision

> Revisions capture consistent state

> Revisions are global

> Similar to SVN

Page 7: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

7

Envers Configuration> To make an entity audited: annotate with

@Audited

> Add event listeners to persistence.xml

Page 8: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

8

What can be audited?> Mappings defined by JPA:

– Simple properties: Strings, Integers, Dates, …– Components– Relations

> Some Hibernate extensions:– Custom types– Collections

Page 9: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

9

Person & Address example again

> Now let's assume both entities are annotated with @Audited

Page 10: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

10

// Revision 1em.getTransaction().begin();Address a1 = new Address(“West st.”, 10);Address a2 = new Address(“East st.”, 15);Person p = new Person(“John”, “Doe”);p.setAddress(a1);entityManager.persist(a1);entityManager.persist(a2);entityManager.persist(p);em.getTransaction().commit();

Page 11: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

11

> Old person data is stored> No code changes – completely transparent to the user

// Revision 2em.getTransaction().begin();p = entityManager.find(Person.class, id);p.setName(“Paul”);p.setAddress(a2);em.getTransaction().commit();

Page 12: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

12

> Transparent traversing of relations

AuditReader ar = AuditReaderFactory.get(em);

// Reading the person at revision 1old_p = ar.find(Person.class, id, 1);assert “John”.equals(old_p.getName());assert a1.equals(old_p.getAddress());

Page 13: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

13

> Transparent traversing of relations: also in case of collections

// Reading the addresses at revision 1old_a1 = ar.find(Address.class, a1_id, 1);assert old_a1.getPersons().size() == 1;assert old_a1.getPersons().contains(p);

old_a2 = ar.find(Address.class, a2_id, 1);assert old_a2.getPersons().size() == 0;

Page 14: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

14

Page 15: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

15

Page 16: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

16

Page 17: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

17

Page 18: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

18

Querying> Entities-at-revision> Revisions-of-entity> Inspired by criteria queries

auditReader.createQuery() .forRevisionsOfEntity(Person.class, false, true) .addProjection(AuditEntity.revisionNumber.count())

.add(AuditEntity.id().eq(person.getId()))

.getSingleResult()

Page 19: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

19

Your data is safe!

Page 20: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

20

Logging data for revisions> With each revision, arbitrary data can be bound (metadata)> For example: user making the changes

> Special entity (@RevisionEntity), storing the metadata> Listener, invoked when a new revision is created

Page 21: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

21

Revision Entity example@Entity@RevisionEntity(ExampleListener.class)public class ExampleRevEnt {

@Id @GeneratedValue @RevisionNumber private Long id;

@RevisionTimestamp private Long timestamp;

@ManyToOne private User modifiedBy;

// Getters, setters, equals, hashCode ...

}

Page 22: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

22

Revision Listener example

public class ExampleListener implements RevisionListener { public void newRevision(Object revEntity) { ExampleRevEnt revEnt = (ExampleRevEnt) revEntity; User currentUser = (User)

Component.getInstance("currentUser"); revEnt.setModifiedBy(currentUser); }}

Page 23: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

23

Envers overall> Unchanged mapping (not intrusive)> Unchanged code (transparent)> Straightforward history reading> Deleted entities aren't gone> Easy to use (@Audited)> Metadata for revisions> Queries

Page 24: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

24

How to use Envers?> 1.2.1.GA released recently> Compatible with Hibernate 3.3> Available as a jar and in JBoss's Maven repository

http://www.jboss.org/envers

Page 25: Hibernate Envers - Jazoon · 2009-06-30 · Hibernate Envers Easy Entity Auditing Adam Warski Level N Consulting 6220. 2 Example: Person & Address > We want to store the history of

Adam Warski www.jboss.org/enverswww.warski.org

Level N Consulting [email protected]