HHH-3556: Envers documentation partially migrated
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@15501 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
7e04164b24
commit
137585b17f
|
@ -0,0 +1,57 @@
|
|||
<?xml version='1.0' encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!ENTITY versionNumber "3.3.0.GA">
|
||||
<!ENTITY copyrightYear "2004">
|
||||
<!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
|
||||
]>
|
||||
|
||||
<book>
|
||||
|
||||
<bookinfo>
|
||||
<title>Hibernate Envers - Easy Entity Auditing</title>
|
||||
<subtitle>Hibernate Envers Reference Documentation</subtitle>
|
||||
<releaseinfo>&versionNumber;</releaseinfo>
|
||||
<productnumber>&versionNumber;</productnumber>
|
||||
<issuenum>1</issuenum>
|
||||
<copyright>
|
||||
<year>©rightYear;</year>
|
||||
<holder>©rightHolder;</holder>
|
||||
</copyright>
|
||||
<xi:include href="legal_notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<!-- include translators... -->
|
||||
</bookinfo>
|
||||
|
||||
<toc/>
|
||||
|
||||
<xi:include href="content/preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="content/quickstart.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="content/example.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="content/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="content/revisionlog.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="content/exceptions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
|
||||
</book>
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
<?xml version='1.0' encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
|
||||
<chapter id="configuration">
|
||||
|
||||
<title>Configuration</title>
|
||||
|
||||
<para>
|
||||
To start working with Envers, all configuration that you must do is add the event
|
||||
listeners to persistence.xml, as described in the <xref linkend="quickstart"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
However, as Envers generates some tables, it is possible to set the prefix and suffix
|
||||
that is added to the entity name to create a versions table for an entity, as well
|
||||
as set the names of the fields that are generated.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In more detail, here are the properites that you can set:
|
||||
</para>
|
||||
|
||||
<table frame="topbot">
|
||||
<title>Envers Configuration Properties</title>
|
||||
<tgroup cols="2">
|
||||
<colspec colname="c1" colwidth="1*"/>
|
||||
<colspec colname="c2" colwidth="1*"/>
|
||||
<colspec colname="c2" colwidth="1*"/>
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Property name</entry>
|
||||
<entry>Default value</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<property>org.hibernate.envers.auditTablePrefix</property>
|
||||
</entry>
|
||||
<entry>
|
||||
|
||||
</entry>
|
||||
<entry>
|
||||
String that will be prepended to the name of an audited entity to create
|
||||
the name of the entity, that will hold audit information.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<property>org.hibernate.envers.auditTableSuffix</property>
|
||||
</entry>
|
||||
<entry>
|
||||
_audit
|
||||
</entry>
|
||||
<entry>
|
||||
String that will be appended to the name of an audited entity to create
|
||||
the name of the entity, that will hold audit information. If you
|
||||
audit an entity with a table name Person, in the default setting Envers
|
||||
will generate a <literal>Person_audit</literal> table to store historical data.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<property>org.hibernate.envers.revisionFieldName</property>
|
||||
</entry>
|
||||
<entry>
|
||||
REV
|
||||
</entry>
|
||||
<entry>
|
||||
Name of a field in the audit entity that will hold the revision number.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<property>org.hibernate.envers.revisionTypeFieldName</property>
|
||||
</entry>
|
||||
<entry>
|
||||
REVTYPE
|
||||
</entry>
|
||||
<entry>
|
||||
Name of a field in the aduit entity that will hold the type of the
|
||||
revision (currently, this can be: add, mod, del).
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<property>org.hibernate.envers.revisionOnCollectionChange</property>
|
||||
</entry>
|
||||
<entry>
|
||||
true
|
||||
</entry>
|
||||
<entry>
|
||||
Should a revision be generated when a not-owned relation field changes
|
||||
(this can be either a collection in a one-to-many relation, or the field
|
||||
using "mappedBy" attribute in a one-to-one relation).
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<property>org.hibernate.envers.warnOnUnsupportedTypes</property>
|
||||
</entry>
|
||||
<entry>
|
||||
false
|
||||
</entry>
|
||||
<entry>
|
||||
TODO: remove
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<property>org.hibernate.envers.doNotAuditOptimisticLockingField</property>
|
||||
</entry>
|
||||
<entry>
|
||||
true
|
||||
</entry>
|
||||
<entry>
|
||||
When true, properties to be used for optimistic locking, annotated with
|
||||
<literal>@Version</literal>, will be automatically not audited
|
||||
(their history won't be stored; it normally doesn't make sense to store it).
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
To change the name of the revision table and its fields (the table, in which the
|
||||
numbers of revisions and their timestamps are stored), you can use the
|
||||
<literal>@RevisionEntity</literal> annotation.
|
||||
For more information, see <xref linkend="revisionlog"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To set the value of any of the properties described above, simply add an entry to
|
||||
your <literal>persistence.xml</literal>. For example:
|
||||
</para>
|
||||
|
||||
<programlisting><persistence-unit ...>
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
<class>...</class>
|
||||
<properties>
|
||||
<property name="hibernate.dialect" ... />
|
||||
<!-- other hibernate properties -->
|
||||
|
||||
<property name="hibernate.ejb.event.post-insert"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
<property name="hibernate.ejb.event.post-update"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
<property name="hibernate.ejb.event.post-delete"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
<property name="hibernate.ejb.event.pre-collection-update"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
<property name="hibernate.ejb.event.pre-collection-remove"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
<property name="hibernate.ejb.event.post-collection-recreate"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
|
||||
<property name="org.hibernate.envers.versionsTableSuffix" value="_V" />
|
||||
<property name="org.hibernate.envers.revisionFieldName" value="ver_rev" />
|
||||
<!-- other envers properties -->
|
||||
</properties>
|
||||
</persistence-unit></programlisting>
|
||||
|
||||
<para>
|
||||
You can also set the name of the versions table on a per-entity basis, using the
|
||||
<literal>@AuditTable</literal> annotation (see also in the javadoc). It may be tedious to add this
|
||||
annotation to every audited entity, so if possible, it's better to use a prefix/suffix.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you have a mapping with secondary tables, version tables for them will be generated in
|
||||
the same way (by adding the prefix and suffix). If you wish to overwrite this behaviour,
|
||||
you can use the <literal>@SecondaryAuditTable</literal> and
|
||||
<literal>@SecondaryAuditTables</literal> annotations.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you want to audit a relation mapped with <literal>@OneToMany+@JoinColumn</literal>,
|
||||
please see <xref linkend="exceptions"/> for a description of the additional
|
||||
<literal>@AuditJoinTable</literal> annotation that you'll probably want to use.
|
||||
</para>
|
||||
</chapter>
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version='1.0' encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
|
||||
<chapter id="example">
|
||||
|
||||
<title>Short example</title>
|
||||
|
||||
<para>
|
||||
For example, using the entities defined above, the following code will generate
|
||||
revision number 1, which will contain two new <literal>Person</literal> and
|
||||
two new <literal>Address</literal> entities:
|
||||
</para>
|
||||
|
||||
<programlisting>entityManager.getTransaction().begin();
|
||||
|
||||
Address address1 = new Address("Privet Drive", 4);
|
||||
Person person1 = new Person("Harry", "Potter", address1);
|
||||
|
||||
Address address2 = new Address("Grimmauld Place", 12);
|
||||
Person person2 = new Person("Hermione", "Granger", address2);
|
||||
|
||||
entityManager.persist(address1);
|
||||
entityManager.persist(address2);
|
||||
entityManager.persist(person1);
|
||||
entityManager.persist(person2);
|
||||
|
||||
entityManager.getTransaction().commit();</programlisting>
|
||||
|
||||
<para>
|
||||
Now we change some entities. This will generate revision number 2, which will contain
|
||||
modifications of one person entity and two address entities (as the collection of
|
||||
persons living at <literal>address2</literal> and <literal>address1</literal> changes):
|
||||
</para>
|
||||
|
||||
<programlisting>entityManager.getTransaction().begin();
|
||||
|
||||
Address address1 = entityManager.find(Address.class, address1.getId());
|
||||
Person person2 = entityManager.find(Person.class, person2.getId());
|
||||
|
||||
// Changing the address's house number
|
||||
address1.setHouseNumber(5)
|
||||
|
||||
// And moving Hermione to Harry
|
||||
person2.setAddress(address1);
|
||||
|
||||
entityManager.getTransaction().commit();</programlisting>
|
||||
|
||||
<para>
|
||||
We can retrieve the old versions (the audit) easily:
|
||||
</para>
|
||||
|
||||
<programlisting>AuditReader reader = AuditReaderFactory.get(entityManager);
|
||||
|
||||
Person person2_rev1 = reader.find(Person.class, person2.getId(), 1);
|
||||
assert person2_rev1.getAddress().equals(new Address("Grimmauld Place", 12));
|
||||
|
||||
Address address1_rev1 = reader.find(Address.class, address1.getId(), 1);
|
||||
assert address1_rev1.getPersons().getSize() == 1;
|
||||
|
||||
// and so on</programlisting>
|
||||
|
||||
</chapter>
|
|
@ -0,0 +1,105 @@
|
|||
<?xml version='1.0' encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
|
||||
<chapter id="exceptions">
|
||||
<title>Mapping exceptions</title>
|
||||
|
||||
<sect1 id="exceptions-wontbesupported">
|
||||
|
||||
<title>What isn't and will not be supported</title>
|
||||
|
||||
<para>
|
||||
Bags (the corresponding Java type is List), as they can contain non-unique elements.
|
||||
The reason is that persisting, for example a bag of String-s, violates a principle
|
||||
of relational databases: that each table is a set of tuples. In case of bags,
|
||||
however (which require a join table), if there is a duplicate element, the two
|
||||
tuples corresponding to the elements will be the same. Hibernate allows this,
|
||||
however Envers (or more precisely: the database connector) will throw an exception
|
||||
when trying to persist two identical elements, because of a unique constraint violation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There are at least two ways out if you need bag semantics:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
use an indexed collection, with the <literal>@IndexColumn</literal> annotation, or
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
provide a unique id for your elements with the <literal>@CollectionId</literal> annotation.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="exceptions-willbesupported" revision="2">
|
||||
|
||||
<title>What isn't and <emphasis>will</emphasis> be supported</title>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
collections of components
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
relations in components
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
joined and table-per-class inheritance
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="exceptions-onetomanyjoincolumn" revision="3">
|
||||
|
||||
<title><literal>@OneToMany</literal>+<literal>@JoinColumn</literal></title>
|
||||
|
||||
<para>
|
||||
When a collection is mapped using these two annotations, Hibernate doesn't
|
||||
generate a join table. Envers, however, has to do this, so that when you read the
|
||||
revisions in which the related entity has changed, you don't get false results.
|
||||
</para>
|
||||
<para>
|
||||
To be able to name the additional join table, there is a special annotation:
|
||||
<literal>@AuditJoinTable</literal>, which has similar semantics to JPA's
|
||||
<literal>@JoinTable</literal>.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version='1.0' encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
|
||||
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
|
||||
<preface id="preface">
|
||||
<title>Preface</title>
|
||||
|
||||
<para>
|
||||
The Envers project aims to enable easy auditing of persistent classes. All that you
|
||||
have to do is annotate your persistent class or some of its properties, that you
|
||||
want to audit, with <literal>@Audited</literal>. For each audited entity, a table
|
||||
will be created, which will hold the history of changes made to the entity. You
|
||||
can then retrieve and query historical data without much effort.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Similarly to Subversion, the library has a concept of revisions. Basically, one
|
||||
transaction is one revision (unless the transaction didn't modify any audited entities).
|
||||
As the revisions are global, having a revision number, you can query for various
|
||||
entities at that revision, retrieving a (partial) view of the database at that
|
||||
revision. You can find a revision number having a date, and the other way round,
|
||||
you can get the date at which a revision was commited.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The library works with Hibernate and Hibernate Annotations or Entity Manager.
|
||||
For the auditing to work properly, the entities must have immutable unique
|
||||
identifiers (primary keys). You can use Envers wherever Hibernate works:
|
||||
standalone, inside JBoss AS, with JBoss Seam or Spring.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Some of the features:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
versioning of all mappings defined by the JPA specification, except joined and
|
||||
table-per-class inheritance
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
versioning of some Hibernate mappings, which extend JPA, like custom types and
|
||||
collections/maps of "simple" types (Strings, Integers, etc.)
|
||||
(see <xref linkend="exceptions"/> for one exception)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
logging data for each revision using a "revision entity"
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
querying historical data
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</preface>
|
|
@ -0,0 +1,148 @@
|
|||
<?xml version='1.0' encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
|
||||
<chapter id="quickstart">
|
||||
<title>Quickstart</title>
|
||||
|
||||
<para>
|
||||
When configuring your persistence unit (the persistence.xml file), add the following event
|
||||
listeners: (this will allow Envers to check if any audited entities were modified)
|
||||
</para>
|
||||
|
||||
<programlisting><persistence-unit ...>
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
<class>...</class>
|
||||
<properties>
|
||||
<property name="hibernate.dialect" ... />
|
||||
<!-- other hibernate properties -->
|
||||
|
||||
<property name="hibernate.ejb.event.post-insert"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
<property name="hibernate.ejb.event.post-update"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
<property name="hibernate.ejb.event.post-delete"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
<property name="hibernate.ejb.event.pre-collection-update"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
<property name="hibernate.ejb.event.pre-collection-remove"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
<property name="hibernate.ejb.event.post-collection-recreate"
|
||||
value="org.hibernate.envers.event.VersionsEventListener" />
|
||||
</properties>
|
||||
</persistence-unit></programlisting>
|
||||
|
||||
<para>
|
||||
Then, annotate your persistent class with <literal>@Audited</literal> - this will make all
|
||||
properties versioned. For example:
|
||||
</para>
|
||||
|
||||
<programlisting>import org.hibernate.envers.Audited;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Column;
|
||||
|
||||
@Entity
|
||||
@Audited // that's the important part :)
|
||||
public class Person {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String surname;
|
||||
|
||||
@ManyToOne
|
||||
private Address address;
|
||||
|
||||
// add getters, setters, constructors, equals and hashCode here
|
||||
}</programlisting>
|
||||
|
||||
<para>
|
||||
And the referenced entity:
|
||||
</para>
|
||||
|
||||
<programlisting>@Entity
|
||||
@Audited
|
||||
public class Address {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
|
||||
private String streetName;
|
||||
|
||||
private Integer houseNumber;
|
||||
|
||||
private Integer flatNumber;
|
||||
|
||||
@OneToMany(mappedBy = "address")
|
||||
private Set<Person> persons;
|
||||
|
||||
// add getters, setters, constructors, equals and hashCode here
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
And that's it! You create, modify and delete the entites as always. If you look
|
||||
at the generated schema, you will notice that it is unchanged by adding auditing
|
||||
for the Address and Person entities. Also, the data they hold is the same. There are,
|
||||
however, two new tables - <literal>Address_audit</literal> and <literal>Person_audit</literal>,
|
||||
which store the historical data, whenever you commit a transaction.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Instead of annotating the whole class and auditing all properties, you can annotate
|
||||
only some persistent properties with <literal>@Audited</literal>. This will cause only
|
||||
these properties to be audited.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can access the audit of an entity using the <literal>AuditReader</literal> interface, which you
|
||||
can obtain when having an open EntityManager. See also the javadocs.
|
||||
</para>
|
||||
|
||||
<programlisting>AuditReader reader = AuditReaderFactory.get(entityManager);
|
||||
Person oldPerson = reader.find(Person.class, personId, revision)
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
The <literal>T find(Class<T> cls, Object primaryKey, Number revision)</literal>
|
||||
method returns an entity with the given primary key, with the data it contained at
|
||||
the given revision. If the entity didn't exist at this revision, <literal>null</literal>
|
||||
is returned. Only the audited properties will be set on the returned entity.
|
||||
The rest will be <literal>null</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can also get a list of revisions at which an entity was modified using the
|
||||
<literal>getRevisions</literal> method, as well as retrieve the date,
|
||||
at which a revision was created using the <literal>getRevisionDate</literal> method.
|
||||
</para>
|
||||
</chapter>
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
<?xml version='1.0' encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
|
||||
<chapter id="revisionlog">
|
||||
|
||||
<title>Logging data for revisions</title>
|
||||
|
||||
<para>
|
||||
Envers provides an easy way to log additional data for each revision. You simply need
|
||||
to annotate one entity with <literal>@RevisionEntity</literal>, and a new instance of
|
||||
this entity will be persisted when a new revision is created (that is, whenever an
|
||||
audited entity is modified). As revisions are global, you can have at most one revisions entity.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This entity must have at least two properties:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
an integer- or long-valued property, annotated with <literal>@RevisionNumber</literal>. Most
|
||||
often, this will be an auto-generated primary key.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
a long-valued property, annotated with <literal>@RevisionTimestamp</literal>. Value of
|
||||
this property will be automatically set by Envers.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
You can either add these properties to your entity, or extend
|
||||
<literal>org.hibernate.envers.DefaultRevisionEntity</literal>, which already has those two properties.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To fill the entity with additional data, you'll need to implement the
|
||||
<literal>org.jboss.envers.RevisionListener</literal> interface. Its newRevision method will
|
||||
be called when a new revision is created, before persisting the revision entity.
|
||||
The implementation should be stateless and thread-safe. The listener then has to be
|
||||
attached to the revisions entity by specifying it as a parameter to the
|
||||
<literal>@RevisionEntity</literal> annotation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A simplest example of a revisions entity, which with each revision associates the
|
||||
username of the user making the change is:
|
||||
</para>
|
||||
|
||||
<programlisting>package org.jboss.envers.example;
|
||||
|
||||
import org.hibernate.envers.RevisionEntity;
|
||||
import org.hibernate.envers.DefaultRevisionEntity;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
@RevisionEntity(ExampleListener.class)
|
||||
public class ExampleRevEntity extends DefaultRevisionEntity {
|
||||
private String username;
|
||||
|
||||
public String getUsername() { return username; }
|
||||
public void setUsername(String username) { this.username = username; }
|
||||
}</programlisting>
|
||||
|
||||
<para>
|
||||
Or, if you don't want to extend any class:
|
||||
</para>
|
||||
|
||||
<programlisting>package org.hibernate.envers.example;
|
||||
|
||||
import org.hibernate.envers.RevisionNumber;
|
||||
import org.hibernate.envers.RevisionTimestamp;
|
||||
import org.hibernate.envers.RevisionEntity;
|
||||
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
@RevisionEntity(ExampleListener.class)
|
||||
public class ExampleRevEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@RevisionNumber
|
||||
private int id;
|
||||
|
||||
@RevisionTimestamp
|
||||
private long timestamp;
|
||||
|
||||
private String username;
|
||||
|
||||
// Getters, setters, equals, hashCode ...
|
||||
}</programlisting>
|
||||
|
||||
<para>
|
||||
An example listener, which, if used in a JBoss Seam application, stores the
|
||||
currently logged in user username:
|
||||
</para>
|
||||
|
||||
<programlisting>package org.hibernate.envers.example;
|
||||
|
||||
import org.hibernate.envers.RevisionListener;
|
||||
import org.jboss.seam.security.Identity;
|
||||
import org.jboss.seam.Component;
|
||||
|
||||
public class ExampleListener implements RevisionListener {
|
||||
public void newRevision(Object revisionEntity) {
|
||||
ExampleRevEntity exampleRevEntity = (ExampleRevEntity) revisionEntity;
|
||||
Identity identity = (Identity) Component.getInstance("org.jboss.seam.security.identity");
|
||||
|
||||
exampleRevEntity.setUsername(identity.getUsername());
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>
|
||||
Having an "empty" revision entity - that is, with no additional properties except the
|
||||
two mandatory ones - is also an easy way to change the names of the table and of the
|
||||
properties in the revisions table automatically generated by Envers.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In case there is no entity annotated with <literal>@RevisionEntity</literal>, a default
|
||||
table will be generated, with the name <literal>REVINFO</literal>.
|
||||
</para>
|
||||
|
||||
</chapter>
|
Loading…
Reference in New Issue