HHH-5446 - Write an envers tutorial guide

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@20345 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2010-09-10 20:19:35 +00:00
parent a4ea233ef8
commit 9a3e4229fd
14 changed files with 659 additions and 277 deletions

View File

@ -8,38 +8,11 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Book_Info.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/preface.xml" />
<part label="I">
<title>Basic Information</title>
<partintro>
<!-- Don't refer to things by Part #, because things could be re-ordered later
<para>
The sections in Part I present basic information you will
likely need to get started utilizing Hibernate
</para>
-->
<para>Set up and begin using Hibernate.</para>
</partintro>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/community.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/obtaining.xml" />
</part>
<part label="II">
<title>Tutorials</title>
<partintro>
<!--
<para>
The sections in Part II dive into illustrative examples of using Hibernate in various
ways. The referenced projects and code are available for download at
<ulink url="http://sourceforge.net/projects/hibernate/files/hibernate/&version;"/>
</para>
-->
<para>
Learn by doing, with guided tutorials. The referenced projects and code are available for download at <ulink url="http://sourceforge.net/projects/hibernate/files/hibernate/&version;"/>.
</para>
</partintro>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/tutorial_native.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/tutorial_annotations.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/tutorial_jpa.xml" />
</part>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/tutorial_envers.xml" />
</book>

View File

@ -1,41 +0,0 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="hibernate-gsg-community">
<title>Hibernate Community</title>
<!-- I removed the para and titled the list instead. I changed gerunds to imperative verbs (Use instead of Using). -->
<itemizedlist>
<title>Get Involved</title>
<listitem>
<para>
Use Hibernate and report any bugs or issues you find. See
<ulink url="http://hibernate.org/issuetracker.html"/> for
details.
</para>
</listitem>
<listitem>
<para>
Try your hand at fixing some bugs or implementing
enhancements. Again, see <ulink
url="http://hibernate.org/issuetracker.html"/>.
</para>
</listitem>
<listitem>
<para>
Engage with the community using mailing lists, forums, IRC, or other ways listed at <ulink url="http://hibernate.org/community.html"/>.
</para>
</listitem>
<listitem>
<para>
Help improve or translate this documentation. Contact us on
the developer mailing list if you have interest.
</para>
</listitem>
<listitem>
<para>
Spread the word. Let the rest of your organization know about the benefits of Hibernate.<!-- I didn't like 'evangelize'. Too many religious overtones. I'd like something stronger than this though. I'll have a think. -->
</para>
</listitem>
</itemizedlist>
</chapter>

View File

@ -9,35 +9,50 @@
<title>Release Bundle Downloads</title>
<para>
The Hibernate team provides release bundles hosted on the SourceForge File Release System, in
<literal>ZIP</literal> and <literal>TGZ</literal> formats. Each release bundle contains <literal>JARs</literal>,
<literal>ZIP</literal>
and
<literal>TGZ</literal>
formats. Each release bundle contains<literal>JARs</literal>,
documentation, source code, and other information.
</para>
<para>
You can download releases of Hibernate, in your chosen format, from the list at <ulink url="http://sourceforge.net/projects/hibernate/files/hibernate3/"/>.
You can download releases of Hibernate, in your chosen format, from the list at
<ulink url="http://sourceforge.net/projects/hibernate/files/hibernate3/"/>.
</para>
<itemizedlist>
<listitem>
<para>
<filename>hibernate3.jar</filename> is an aggregation of all the Hibernate Core classes.
<filename>hibernate3.jar</filename>
is an aggregation of all the Hibernate Core classes.
This must be included in your project's classpath.
</para>
</listitem>
<listitem>
<para>
The <filename>lib/required/</filename> directory contains JARs Hibernate requires. All the jars in this directory must also be included in your project's classpath as well.
The
<filename>lib/required/</filename>
directory contains JARs Hibernate requires. All the jars in this directory must also be included in
your project's classpath as well.
</para>
<important>
<para>
The <filename>slf4j</filename> JAR has additional
The
<filename>slf4j</filename>
JAR has additional
requirements for it to function properly. The exact
requirements depend on your logging back-end. See <ulink
url="http://slf4j.org/">slf4j site</ulink> for details.
requirements depend on your logging back-end. See
<ulink
url="http://slf4j.org/">slf4j site
</ulink>
for details.
</para>
</important>
</listitem>
<listitem>
<para>
The <filename>/lib/jpa/</filename> directory contains the
The
<filename>/lib/jpa/</filename>
directory contains the
<ulink url="http://jcp.org/en/jsr/detail?id=317">JPA</ulink>
API JAR. This JAR needs to be in your project's classpath if
you want to use the JPA APIs or JPA annotations.
@ -48,56 +63,54 @@
<section id="hibernate-gsg-setup-mavenRepoArtifacts">
<title>Maven Repository Artifacts</title>
<note>
<para>
The authoritative repository for Hibernate artifacts is the
JBoss Maven repository. The team responsible for the JBoss
Maven repository maintains a number of Wiki pages that contain
important information.
</para>
<!-- lists inside <para> don't work in Publican, and you don't lose
anything by putting them outside the para. -->
<variablelist>
<itemizedlist>
<title>Maven Repository Wiki Pages</title>
<varlistentry>
<term><ulink url="http://community.jboss.org/docs/DOC-14900">http://community.jboss.org/docs/DOC-14900</ulink></term>
<listitem>
<para>
<ulink url="http://community.jboss.org/docs/DOC-14900"/> -
General information about the repository.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><ulink url="http://community.jboss.org/docs/DOC-15170">http://community.jboss.org/docs/DOC-15170</ulink></term>
<listitem>
<para>
Information about setting up the JBoss repositories in order to do development work on JBoss projects themselves.
<ulink url="http://community.jboss.org/docs/DOC-15170"/> -
Information about setting up the JBoss repositories in
order to do development work on JBoss projects themselves.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><ulink url="http://community.jboss.org/docs/DOC-15169">http://community.jboss.org/docs/DOC-15169</ulink></term>
<listitem>
<para>
Information about setting up access to the repository to use JBoss projects as part of your own software.
<ulink url="http://community.jboss.org/docs/DOC-15169"/> -
Information about setting up access to the repository to
use JBoss projects as part of your own software.
</para>
</listitem>
</varlistentry>
</variablelist>
</itemizedlist>
</note>
<para>
Hibernate produces a number of artifacts (all under the org.hibernate groupId):
</para>
<variablelist>
<title>Hibernate Artifacts under groupId<systemitem>org.hibernate</systemitem></title>
<title>Hibernate Artifacts under groupId <systemitem>org.hibernate</systemitem>
</title>
<varlistentry>
<term>hibernate-core</term>
<listitem>
<para>
The main artifact, which contains all the Hibernate classes, in
package <package>org.hibernate</package>. You need these to
package<package>org.hibernate</package>. You need these to
build applications using the native Hibernate APIs. It includes
capabilities for using native Hibernate mapping in
<filename>hbm.xml</filename> files, as well as annotations.
<filename>hbm.xml</filename>
files, as well as annotations.
</para>
</listitem>
</varlistentry>
@ -105,9 +118,8 @@
<term>hibernate-entitymanager</term>
<listitem>
<para>
Represents Hibernate's implementation of
<application>JPA</application>, as specified at<ulink
url="http://jcp.org/en/jsr/detail?id=317" />.
Represents Hibernate's implementation of <phrase>JPA</phrase>, as specified at
<ulink url="http://jcp.org/en/jsr/detail?id=317"/>.
</para>
<para>
This artifact depends on <systemitem>hibernate-core</systemitem>
@ -122,9 +134,8 @@
to your entities.
</para>
<para>
This artifact depends on both
<systemitem>hibernate-core</systemitem> and
<systemitem>hibernate-entitymanager</systemitem>.
This artifact depends on both <systemitem>hibernate-core</systemitem>
and <systemitem>hibernate-entitymanager</systemitem>.
</para>
</listitem>
</varlistentry>
@ -132,13 +143,14 @@
<term>hibernate-c3p0</term>
<listitem>
<para>
Provides integration between Hibernate and the
<application>C3P0</application> connection pool library. See
<ulink url="http://sourceforge.net/projects/c3p0/" /> for
information about <application>C3P0</application>.
Provides integration between Hibernate and the <application>C3P0</application> connection
pool library. See <ulink url="http://sourceforge.net/projects/c3p0/"/> for information
about <application>C3P0</application>.
</para>
<para>
This artifact depends on <systemitem>hibernate-core</systemitem>, but is generally included in a project as a runtime dependency. It pulls in the <application>C3P0</application> dependencies automatically.
This artifact depends on <systemitem>hibernate-core</systemitem>, but is generally included
in a project as a runtime dependency. It pulls in the <application>C3P0</application>
dependencies automatically.
</para>
</listitem>
</varlistentry>
@ -146,16 +158,14 @@
<term>hibernate-proxool</term>
<listitem>
<para>
Provides integration between Hibernate and the
<application>Proxool</application> connection pool library. See
<ulink url="http://proxool.sourceforge.net/" /> for more
information about this library. library.
Provides integration between Hibernate and the <application>Proxool</application> connection
pool library. See <ulink url="http://proxool.sourceforge.net/"/> for more information about
this library.
</para>
<para>
This artifact depends on
<systemitem>hibernate-core</systemitem>, but is generally
included in a project as a runtime dependency. It pulls in the
<application>Proxool</application> dependencies automatically..
This artifact depends on <systemitem>hibernate-core</systemitem>, but is generally included
in a project as a runtime dependency. It pulls in the <application>Proxool</application>
dependencies automatically..
</para>
</listitem>
</varlistentry>
@ -163,16 +173,14 @@
<term>hibernate-ehcache</term>
<listitem>
<para>
Privides integration between Hibernate and
<application>EhCache</application>, as a second-level cache. See
<ulink url="http://ehcache.sourceforge.net/" /> for more
information about <application>EhCache</application>.
Privides integration between Hibernate and <application>EhCache</application>, as a
second-level cache. See <ulink url="http://ehcache.sourceforge.net/"/> for more
information about<application>EhCache</application>.
</para>
<para>
This artifact depends on
<systemitem>hibernate-core</systemitem>, but is generally
included in a project as a runtime dependency. It pulls in the
<application>Ehcache</application> dependencies automatically.
This artifact depends on <systemitem>hibernate-core</systemitem>, but is generally included
in a project as a runtime dependency. It pulls in the <application>Ehcache</application>
dependencies automatically.
</para>
</listitem>
</varlistentry>
@ -180,12 +188,14 @@
<term>hibernate-infinispan</term>
<listitem>
<para>
Provides integration between Hibernate
and <application>Infinispan</application>, as a second-level cache. See <ulink url="http://jboss.org/infinispan" /> for more information about <application>Infinispan</application>.
Provides integration between Hibernate and <application>Infinispan</application>, as a
second-level cache. See <ulink url="http://jboss.org/infinispan"/> for more information
about <application>Infinispan</application>.
</para>
<para>
This artifact depends on <systemitem>hibernate-core</systemitem>, but is generally included in a project as a runtime
dependency. It pulls in the <application>Infinispan</application> dependencies automatically.
This artifact depends on <systemitem>hibernate-core</systemitem>, but is generally included
in a project as a runtime dependency. It pulls in the <application>Infinispan</application>
dependencies automatically.
</para>
</listitem>
</varlistentry>
@ -193,13 +203,13 @@
<term>hibernate-jbosscache</term>
<listitem>
<para>
Provides integration between Hibernate
and <application>JBossCache</application>, as a second-level cache. See <ulink url="http://jboss.org/jbosscache" /> for information about <application>JBossCache</application>.
Provides integration between Hibernate and <application>JBossCache</application>, as a
second-level cache. See <ulink url="http://jboss.org/jbosscache"/> for information about
<application>JBossCache</application>.
</para>
<para>
This artifact depends on <systemitem>hibernate-core</systemitem>,
but is generally included in a project as a runtime dependency.
It pulls in the <application>JBossCache</application>
This artifact depends on <systemitem>hibernate-core</systemitem>, but is generally included
in a project as a runtime dependency. It pulls in the <application>JBossCache</application>
dependencies automatically.
</para>
</listitem>
@ -208,13 +218,14 @@
<term>hibernate-oscache</term>
<listitem>
<para>
Provides integration between Hibernate
and <application>OSCache</application> as a second-level cache. See <ulink url="http://www.opensymphony.com/oscache/" /> for information about <application>OSCache</application>.
Provides integration between Hibernate and <application>OSCache</application> as a
second-level cache. See <ulink url="http://www.opensymphony.com/oscache/"/> for information
about <application>OSCache</application>.
</para>
<para>
This artifact depends on <systemitem>hibernate-core</systemitem>,
but is generally included in a project as a runtime dependency.
It pulls in the OSCache dependencies automatically.
This artifact depends on <systemitem>hibernate-core</systemitem>, but is generally included
in a project as a runtime dependency. It pulls in the <application>OSCache</application>
dependencies automatically.
</para>
</listitem>
</varlistentry>
@ -222,11 +233,14 @@
<term>hibernate-swarmcache</term>
<listitem>
<para>
Provides integration between Hibernate
and <application>SwarmCache</application>, as a second-level cache. See <ulink url="http://swarmcache.sourceforge.net/" /> for more information about <application>SwarmCache</application>.
Provides integration between Hibernate and <application>SwarmCache</application>, as a
second-level cache. See <ulink url="http://swarmcache.sourceforge.net/"/> for more information
about <application>SwarmCache</application>.
</para>
<para>
This artifact depends on <systemitem>hibernate-core</systemitem>, but is generally included in a project as a runtime dependency. It pulls in the <application>SwarmCache</application> dependencies automatically.
This artifact depends on <systemitem>hibernate-core</systemitem>, but is generally included
in a project as a runtime dependency. It pulls in the <application>SwarmCache</application>
dependencies automatically.
</para>
</listitem>
</varlistentry>

View File

@ -85,4 +85,47 @@
representation to a graph of objects.
</para>
<section>
<title>Get Involved</title>
<itemizedlist>
<listitem>
<para>
Use Hibernate and report any bugs or issues you find. See
<ulink url="http://hibernate.org/issuetracker.html"/> for details.
</para>
</listitem>
<listitem>
<para>
Try your hand at fixing some bugs or implementing enhancements. Again, see
<ulink url="http://hibernate.org/issuetracker.html"/>.
</para>
</listitem>
<listitem>
<para>
Engage with the community using mailing lists, forums, IRC, or other ways listed at
<ulink url="http://hibernate.org/community.html"/>.
</para>
</listitem>
<listitem>
<para>
Help improve or translate this documentation. Contact us on
the developer mailing list if you have interest.
</para>
</listitem>
<listitem>
<para>
Spread the word. Let the rest of your organization know about the benefits of
Hibernate.<!-- I didn't like 'evangelize'. Too many religious overtones. I'd like something stronger than this though. I'll have a think. -->
</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Tutorial code</title>
<para>
The referenced projects and code for the tutorials in this guide are available at
<ulink url="files/hibernate-tutorials.zip"/>.
</para>
</section>
</preface>

View File

@ -0,0 +1,72 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="hibernate-gsg-tutorial-envers">
<title>Tutorial Using Envers</title>
<para>
This tutorial is located within the download bundle under <filename>envers</filename> and illustrates
<itemizedlist>
<listitem>
<para>
configuring Envers
</para>
</listitem>
<listitem>
<para>
using the Envers APIs to look back through history
</para>
</listitem>
</itemizedlist>
</para>
<section id="hibernate-gsg-tutorial-envers-config">
<title><filename>persistence.xml</filename></title>
<para>
This file was discussed in the <phrase>JPA</phrase> tutorial, and is largely the same here. The major
difference is the set of properties defining <firstterm><phrase>listeners</phrase></firstterm>.
Essentially this enables envers to recieve notfications from Hibernate processing of certain
<firstterm><phrase>events</phrase></firstterm> such as an entity being saved or updated.
</para>
</section>
<section id="hibernate-gsg-tutorial-envers-entity">
<title>The annotated entity Java class</title>
<para>
Again, the entity is largely the same as seen in the <phrase>JPA</phrase> tutorial. The major
difference to notice is the addition of the <interfacename>@org.hibernate.envers.Audited</interfacename>
annotation which tells Envers to automatically track changes to this entity.
</para>
</section>
<section id="hibernate-gsg-tutorial-envers-test">
<title>Example code</title>
<para>
Again, this tutorial makes use of the <phrase>JPA</phrase> APIs. However, the code also makes a
revision to one of the entites and then uses the Envers API to pull back the initial revision
as well as the updated revision.
</para>
<example id="hibernate-gsg-tutorial-envers-test-api">
<title>Using the <interfacename>org.hibernate.envers.AuditReader</interfacename></title>
<programlisting role="JAVA">public void testBasicUsage() {
...
AuditReader reader = AuditReaderFactory.get( entityManager );
Event firstRevision = reader.find( Event.class, 2L, 1 );
...
Event secondRevision = reader.find( Event.class, 2L, 2 );
...
}</programlisting>
</example>
<para>
First an <interfacename>org.hibernate.envers.AuditReader</interfacename> is obtained
from the <classname>org.hibernate.envers.AuditReaderFactory</classname> wrapping the
<interfacename>javax.persistence.EntityManager</interfacename>.
</para>
<para>
Then the <methodname>find</methodname> methid is used to retrieve specific revisions of the entity. The
first call reads "find revision number 1 of Event with id 2". The second call reads "find revision
number 2 of Event with id 2".
</para>
</section>
</chapter>

View File

@ -40,9 +40,7 @@
<important>
<para>
The built-in Hibernate connection pool is in no way intended for production use. It
lacks several features found on any decent connection pool. See the section
<citetitle pubwork="section">JDBC Connections</citetitle> in the
<citetitle pubwork="chapter">Database Access</citetitle> chapter of the
lacks several features found on any decent connection pool. See the section discussion in
<citetitle pubwork="book">Hibernate Developer Guide</citetitle> for further information.
</para>
</important>
@ -55,10 +53,8 @@
<tip>
<para>
In most cases, Hibernate is able to properly determine which dialect to use which is invaluable if
your application targets multiple databases. See the section
<citetitle pubwork="section">Database Dialects</citetitle> in the
<citetitle pubwork="chapter">Database Access</citetitle> chapter of the
<citetitle pubwork="book">Hibernate Developer Guide</citetitle> for further information.
your application targets multiple databases. This is discussed in detail in the
<citetitle pubwork="book">Hibernate Developer Guide</citetitle>
</para>
</tip>
@ -162,6 +158,7 @@
</para>
<important>
<!-- Again, perhaps more sense moving this to the Dev Guide -->
<para>
It is not strictly necessary for the <literal>id</literal> element to map to the table's actual
primary key column(s), but it is the normal convention. Tables mapped in Hibernate do not even
@ -217,6 +214,7 @@
</para>
<tip>
<!-- This tip probably makes more sense in the Dev Guide -->
<para>
Hibernate makes this mapping type determination using reflection when the mapping files are
processed. This process can take time and resources. If startup performance is important, consider

View File

@ -33,7 +33,8 @@ import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* TODO : javadoc
* Illustrates the use of Hibernate native APIs. The code here is unchanged from the {@code basic} example, the
* only difference being the use of annotations to supply the metadata instead of Hibernate mapping files.
*
* @author Steve Ebersole
*/
@ -55,6 +56,7 @@ public class AnnotationsIllustrationTest extends TestCase {
}
}
@SuppressWarnings({ "unchecked" })
public void testBasicUsage() {
// create a couple of events...
Session session = sessionFactory.openSession();

View File

@ -33,7 +33,7 @@ import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* TODO : javadoc
* Illustrates use of Hibernate native APIs.
*
* @author Steve Ebersole
*/

View File

@ -32,7 +32,7 @@ import javax.persistence.Persistence;
import junit.framework.TestCase;
/**
* TODO : javadoc
* Illustrates basic use of Hibernate as a JPA provider.
*
* @author Steve Ebersole
*/

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ Copyright (c) 2010, Red Hat Inc. 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 Inc.
~
~ 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
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>hibernate-tutorials</artifactId>
<groupId>org.hibernate.tutorials</groupId>
<version>3.6.0-SNAPSHOT</version>
</parent>
<artifactId>hibernate-tutorial-envers</artifactId>
<name>Hibernate Envers Tutorial</name>
<description>Hibernate tutorial illustrating basic set up and use of Envers</description>
<properties>
<!-- Skip artifact deployment -->
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,105 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. 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 Inc.
*
* 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
*/
package org.hibernate.tutorial.envers;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import junit.framework.TestCase;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;
/**
* Illustrates the set up and use of Envers.
* <p>
* This example is different from the others in that we really need to save multiple revisions to the entity in
* order to get a good look at Envers in action.
*
* @author Steve Ebersole
*/
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();
}
}

View File

@ -0,0 +1,92 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. 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 Inc.
*
* 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
*/
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 {
private Long id;
private String title;
private Date date;
public Event() {
// this form used by Hibernate
}
public Event(String title, Date date) {
// for application use, to create new events
this.title = title;
this.date = date;
}
@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment")
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "EVENT_DATE")
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public int hashCode() {
int result = title.hashCode();
result = 31 * result + date.hashCode();
return result;
}
}

View File

@ -0,0 +1,64 @@
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ Copyright (c) 2010, Red Hat Inc. 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 Inc.
~
~ 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
-->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="org.hibernate.tutorial.envers">
<description>
Persistence unit for the Envers tutorial of the Hibernate Getting Started Guide
</description>
<class>org.hibernate.tutorial.envers.Event</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create" />
<!-- These entries needed to enable Envers -->
<!-- todo : ?? http://opensource.atlassian.com/projects/hibernate/browse/HHH-5551 ?? -->
<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" />
</properties>
</persistence-unit>
</persistence>

View File

@ -43,6 +43,7 @@
<module>basic</module>
<module>annotations</module>
<module>entitymanager</module>
<module>envers</module>
</modules>
<dependencies>