HHH-6036 - integration documentation generation

This commit is contained in:
Steve Ebersole 2011-03-29 15:14:09 -05:00
parent ef3830b7ee
commit ba71fe0132
41 changed files with 789 additions and 4811 deletions

View File

@ -6,6 +6,7 @@ buildDir = "target"
repositories {
mavenCentral()
mavenLocal()
mavenRepo name: "jboss", urls: "http://repository.jboss.org/nexus/content/groups/public/"
}

View File

@ -1,20 +1,26 @@
buildscript {
repositories {
mavenCentral()
mavenLocal()
mavenRepo name: "jboss", urls: "http://repository.jboss.org/nexus/content/groups/public/"
mavenRepo urls: "file://" + System.getProperty('user.home') + "/.m2/repository/"
}
dependencies {
classpath 'org.jboss.jdocbook:gradle-jdocbook:1.1.0'
}
}
apply plugin: "java"
apply plugin: "jdocbook"
dependencies {
jdocbookStyles "org.hibernate:hibernate-jdocbook-style:2.0.1"
}
defaultTasks 'buildDocs'
jdocbook {
format('html_single') {
// apply shared formatting config ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
format('html_single') {
finalName = "index.html"
stylesheet = "classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml-single.xsl"
}
@ -22,30 +28,50 @@ jdocbook {
finalName = "index.html"
stylesheet = "classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml.xsl"
}
format {
name = "pdf"
finalName = "hibernate_reference.pdf"
stylesheet = "classpath:/xslt/org/hibernate/jdocbook/xslt/pdf.xsl"
}
// book-specific config ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
quickstart {
masterSourceDocumentName = 'Hibernate_Getting_Started_Guide.xml'
// only html supported due to tutorials.zip
// formats.pdf.enable = false
}
devguide {
masterSourceDocumentName = 'Hibernate_Development_Guide.xml'
formats.pdf.enable = false
}
envers {
masterSourceDocumentName = 'Hibernate_Envers_-_Easy_Entity_Auditing.xml'
formats.pdf.finalName = "hibernate_envers_reference.pdf"
}
jbosscache2 {
masterSourceDocumentName = 'Hibernate_JBC_Reference.xml'
formats.pdf.finalName = "hibernate_jbc_reference.pdf"
}
manual {
masterSourceDocumentName = 'HIBERNATE_-_Relational_Persistence_for_Idiomatic_Java.xml'
translation = ['de-DE','es-ES','fr-FR','ja-JP','pt-BR','zh-CN']
}
quickstart {
masterSourceDocumentName = 'Hibernate_Getting_Started_Guide.xml'
formats.pdf.enable = false
}
// todo : need to remove this once all content moved to devguide
// manual {
// masterSourceDocumentName = 'HIBERNATE_-_Relational_Persistence_for_Idiomatic_Java.xml'
// translation = ['de-DE','es-ES','fr-FR','ja-JP','pt-BR','zh-CN']
// }
}
task buildTutorialZip(type: Zip) {
destinationDir = file( "target/work/tutorials" )
archiveName = 'hibernate-tutorials.zip'
from 'src/main/docbook/quickstart/tutorials'
// todo : this part does not work. Asked on mailing list
filter(
org.apache.tools.ant.filters.ReplaceTokens,
tokens: [VERSION: project.version]
)
}
buildDocs.dependsOn buildTutorialZip
buildDocs.doLast {
for ( File languageDir : dirList( "target/docbook/publish/quickstart" ) ) {
for ( File formatDir : dirList( languageDir ) ) {
final File copyDir = new File( formatDir, "files" );
copyDir.mkdirs();
ant.copy( file: buildTutorialZip.archivePath.getAbsolutePath(), todir: copyDir.getAbsolutePath() )
}
}
}
File[] dirList(String dirName) {
return dirList( (File) file(dirName) );
}
File[] dirList(File dir) {
return dir.listFiles({file -> file.isDirectory() } as FileFilter).sort();
}

View File

@ -74,6 +74,9 @@
<othercredit class="translator" lang="es-ES">
<othername><![CDATA[Bernardo Antonio Buffa Colom&#x00e9]]></othername>
<email>kreimer@bbs.frc.utn.edu.ar</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<!--
@ -84,30 +87,51 @@
<othercredit class="translator" lang="fr-FR">
<firstname>Vincent</firstname>
<surname>Ricard</surname>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Sebastien</firstname>
<surname>Cesbron</surname>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Michael</firstname>
<surname>Courcy</surname>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Vincent</firstname>
<surname>Giguère</surname>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Baptiste</firstname>
<surname>Mathus</surname>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Emmanuel</firstname>
<surname>Bernard</surname>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Anthony</firstname>
<surname>Patricio</surname>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<!--
@ -119,60 +143,96 @@
<firstname>Alvaro</firstname>
<surname>Netto</surname>
<email>alvaronetto@cetip.com.br</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Anderson</firstname>
<surname>Braulio</surname>
<email>andersonbraulio@gmail.com</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Daniel Vieira</firstname>
<surname>Costa</surname>
<email>danielvc@gmail.com</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Francisco</firstname>
<surname>gamarra</surname>
<email>francisco.gamarra@gmail.com</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Gamarra</firstname>
<email>mauricio.gamarra@gmail.com</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Luiz Carlos</firstname>
<surname>Rodrigues</surname>
<email>luizcarlos_rodrigues@yahoo.com.br</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Marcel</firstname>
<surname>Castelo</surname>
<email>marcel.castelo@gmail.com</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Paulo</firstname>
<surname>César</surname>
<email>paulocol@gmail.com</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Pablo L.</firstname>
<surname>de Miranda</surname>
<email>pablolmiranda@gmail.com</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Renato</firstname>
<surname>Deggau</surname>
<email>rdeggau@gmail.com</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Rogério</firstname>
<surname>Araújo</surname>
<email>rgildoaraujo@yahoo.com.br</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Wanderson</firstname>
<surname>Siqueira</surname>
<email>wandersonxs@gmail.com</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
<!--
@ -188,6 +248,9 @@
</affiliation>
<contrib>Translation Lead</contrib>
<email>caoxg@yahoo.com</email>
<affiliation>
<shortaffil>Translation</shortaffil>
</affiliation>
</othercredit>
</authorgroup>

View File

@ -23,7 +23,7 @@
~ Boston, MA 02110-1301 USA
-->
<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "Hibernate_Developer_Guide.ent">
<!ENTITY % BOOK_ENTITIES SYSTEM "Hibernate_Development_Guide.ent">
%BOOK_ENTITIES;
]>

View File

@ -1,13 +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" [
<!ENTITY % BOOK_ENTITIES SYSTEM "Hibernate_Development_Guide.ent">
%BOOK_ENTITIES;
]>
<chapter>
<title>Test Chapter</title>
<para>
</para>
</chapter>

View File

@ -10,7 +10,7 @@
<title>Connection</title>
<para>
Hibernate connects to databases on behalf of your applications. It can connect through a variety of different
machanisms, including:
mechanisms, including:
</para>
<itemizedlist>
<listitem><para>Stand-alone built-in connection pool</para></listitem>
@ -47,11 +47,6 @@
The DTD in the configuration file used in this example is required.
</para>
</note>
<warning>
<para>
Do not use the HSQL database for production.
</para>
</warning>
<section>
<title>Programatic configuration</title>
@ -244,15 +239,11 @@
<section id="configuring-dialects">
<title>Dialects</title>
<para>
Although SQL is relatively standardized, each database vendor uses a subset of supported syntax. This is reffered
to as a <firstterm>dialect</firstterm>.
</para>
<para>
Always set the <property>hibernate.dialect</property> property to the correct
<classname>org.hibernate.dialect.Dialect</classname> subclass for your database. If you specify a dialect,
Hibernate uses sensible defaults for some of the other properties listed above, saving you the effort of setting
them manually.
Although SQL is relatively standardized, each database vendor uses a subset of supported syntax. This is referred
to as a <firstterm>dialect</firstterm>. Hibernate handles variations across these dialects through its
<classname>org.hibernate.dialect.Dialect</classname> class and the various subclasses for each vendor dialect.
</para>
<table>
<title>Supported database dialects</title>
<tgroup cols="2">
@ -322,8 +313,8 @@
<entry>org.hibernate.dialect.MySQLMyISAMDialect</entry>
</row>
<row>
<entry>Oracle (any version)</entry>
<entry>org.hibernate.dialect.OracleDialect</entry>
<entry>Oracle 8i</entry>
<entry>org.hibernate.dialect.Oracle8iDialect</entry>
</row>
<row>
<entry>Oracle 9i</entry>
@ -360,8 +351,41 @@
</tbody>
</tgroup>
</table>
<section>
<title>Specifying the Dialect to use</title>
<para>
The developer may manually specify the Dialect to use by setting the
<property>hibernate.dialect</property> configuration property to the name of a specific
<classname>org.hibernate.dialect.Dialect</classname> class to use.
</para>
</section>
<section>
<title>Dialect resolution</title>
<para>
Assuming a <interfacename>org.hibernate.connection.ConnectionProvider</interfacename> has been
set up, Hibernate will attempt to automatically determine the Dialect to use based on the
<interfacename>java.sql.DatabaseMetaData</interfacename> reported by a
<interfacename>java.sql.Connection</interfacename> obtained from that
<interfacename>org.hibernate.connection.ConnectionProvider</interfacename>.
</para>
<para>
This functionality is provided by a series of
<interfacename>org.hibernate.dialect.resolver.DialectResolver</interfacename> instances registered
with Hibernate internally. Hibernate comes with a standard set of recognitions. If your application
requires extra Dialect resolution capabilities, it would simply register a custom implementation
of <interfacename>org.hibernate.dialect.resolver.DialectResolver</interfacename> as follows:
</para>
<!-- document an example using the service registry -->
<para>
Registered <interfacename>org.hibernate.dialect.resolver.DialectResolver</interfacename> are
<emphasis>prepended</emphasis> to an internal list of resolvers, so they take precedence
before any already registered resolvers including the standard one.
</para>
</section>
</section>
<section>
<title>Automatic schema generation with SchemaExport</title>
<para>

View File

@ -0,0 +1,459 @@
<?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" [
<!ENTITY % BOOK_ENTITIES SYSTEM "Hibernate_Development_Guide.ent">
%BOOK_ENTITIES;
]>
<chapter>
<title>Envers</title>
<preface>
<title>Preface</title>
<para>
The aim of Hibernate Envers is to provide historical versioning of your application's entity data. Much
like source control management tools such as Subversion or Git, Hibernate Envers manages a notion of revisions
if your application data through the use of audit tables. Each transaction relates to one global revision number
which can be used to identify groups of changes (much like a change set in source control). 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 committed.
</para>
</preface>
<section>
<title>Configuration</title>
<para>
It is possible to configure various aspects of Hibernate Envers behavior, such as table names, etc.
</para>
<table frame="topbot">
<title>Envers Configuration Properties</title>
<tgroup cols="3">
<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.audit_table_prefix</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.audit_table_suffix</property>
</entry>
<entry>
_AUD
</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_AUD</literal> table to store
historical data.
</entry>
</row>
<row>
<entry>
<property>org.hibernate.envers.revision_field_name</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.revision_type_field_name</property>
</entry>
<entry>
REVTYPE
</entry>
<entry>
Name of a field in the audit entity that will hold the type of the revision (currently,
this can be: add, mod, del).
</entry>
</row>
<row>
<entry>
<property>org.hibernate.envers.revision_on_collection_change</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.do_not_audit_optimistic_locking_field</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>
<row>
<entry>
<property>org.hibernate.envers.store_data_at_delete</property>
</entry>
<entry>
false
</entry>
<entry>
Should the entity data be stored in the revision when the entity is deleted (instead of only
storing the id and all other properties as null). This is not normally needed, as the data is
present in the last-but-one revision. Sometimes, however, it is easier and more efficient to
access it in the last revision (then the data that the entity contained before deletion is
stored twice).
</entry>
</row>
<row>
<entry>
<property>org.hibernate.envers.default_schema</property>
</entry>
<entry>
null (same schema as table being audited)
</entry>
<entry>
The default schema name that should be used for audit tables. Can be overridden using the
<literal>@AuditTable(schema="...")</literal> annotation. If not present, the schema will
be the same as the schema of the table being audited.
</entry>
</row>
<row>
<entry>
<property>org.hibernate.envers.default_catalog</property>
</entry>
<entry>
null (same catalog as table being audited)
</entry>
<entry>
The default catalog name that should be used for audit tables. Can be overridden using the
<literal>@AuditTable(catalog="...")</literal> annotation. If not present, the catalog will
be the same as the catalog of the normal tables.
</entry>
</row>
<row>
<entry>
<property>org.hibernate.envers.audit_strategy</property>
</entry>
<entry>
org.hibernate.envers.strategy.DefaultAuditStrategy
</entry>
<entry>
The audit strategy that should be used when persisting audit data. The default stores only
the revision, at which an entity was modified. An alternative, the
<literal>org.hibernate.envers.strategy.ValidityAuditStrategy</literal> stores both the
start revision and the end revision. Together these define when an audit row was valid,
hence the name ValidityAuditStrategy.
</entry>
</row>
<row>
<entry>
<property>org.hibernate.envers.audit_strategy_validity_end_rev_field_name</property>
</entry>
<entry>
REVEND
</entry>
<entry>
The column name that will hold the end revision number in audit entities. This property is
only valid if the validity audit strategy is used.
</entry>
</row>
<row>
<entry>
<property>org.hibernate.envers.audit_strategy_validity_store_revend_timestamp</property>
</entry>
<entry>
false
</entry>
<entry>
Should the timestamp of the end revision be stored, until which the data was valid, in
addition to the end revision itself. This is useful to be able to purge old Audit records
out of a relational database by using table partitioning. Partitioning requires a column
that exists within the table. This property is only evaluated if the ValidityAuditStrategy
is used.
</entry>
</row>
<row>
<entry>
<property>org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name</property>
</entry>
<entry>
REVEND_TSTMP
</entry>
<entry>
Column name of the timestamp of the end revision until which the data was valid. Only used
if the ValidityAuditStrategy is used, and
<property>org.hibernate.envers.audit_strategy_validity_store_revend_timestamp</property>
evaluates to true
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section>
<title>Choosing an audit strategy</title>
<para>
After the basic configuration it is important to choose the audit strategy that will be used to persist
and retrieve audit information. There is a trade-off between the performance of persisting and the
performance of querying the audit information. Currently there two audit strategies.
</para>
<orderedlist>
<listitem>
<para>
The default audit strategy persists the audit data together with a start revision. For each row
inserted, updated or deleted in an audited table, one or more rows are inserted in the audit
tables, together with the start revision of its validity. Rows in the audit tables are never
updated after insertion. Queries of audit information use subqueries to select the applicable
rows in the audit tables. These subqueries are notoriously slow and difficult to index.
</para>
</listitem>
<listitem>
<para>
The alternative is a validity audit strategy. This strategy stores the start-revision and the
end-revision of audit information. For each row inserted, updated or deleted in an audited table,
one or more rows are inserted in the audit tables, together with the start revision of its
validity. But at the same time the end-revision field of the previous audit rows (if available)
are set to this revision. Queries on the audit information can then use 'between start and end
revision' instead of subqueries as used by the default audit strategy.
</para>
<para>
The consequence of this strategy is that persisting audit information will be a bit slower,
because of the extra updates involved, but retrieving audit information will be a lot faster.
This can be improved by adding extra indexes.
</para>
</listitem>
</orderedlist>
</section>
<section id="envers-revisionlog">
<title>Revision Log</title>
<subtitle>Logging data for revisions</subtitle>
<para>
When Envers starts a new revision, it creates a new <firstterm>revision entity</firstterm> which stores
information about the revision. By default, that includes just
</para>
<orderedlist>
<listitem>
<para>
<term>revision number</term> - An integral value (<literal>int/Integer</literal> or
<literal>long/Long</literal>). Essentially the primary key of the revision
</para>
<para>
<term>revision timestamp</term> - either a <literal>long/Long</literal> or
<classname>java.util.Date</classname> value representing the instant at which the revision was made.
When using a <classname>java.util.Date</classname>, instead of a <literal>long/Long</literal> for
the revision timestamp, take care not to store it to a column data type which will loose precision.
</para>
</listitem>
</orderedlist>
<para>
Envers handles this information as an entity. By default it uses its own internal class to act as the
entity. You can, however, supply your own approach to collecting this information which might be useful to
capture additional details such as who made a change or the ip address from which the request came. There
are 2 things you need to make this work.
</para>
<orderedlist>
<listitem>
<para>
First, you will need to tell Envers about the entity you wish to use. Your entity must use the
<interfacename>@org.hibernate.envers.RevisionEntity</interfacename> annotation. It must
define the 2 attributes described above annotated with
<interfacename>@org.hibernate.envers.RevisionNumber</interfacename> and
<interfacename>@org.hibernate.envers.RevisionTimestamp</interfacename>, respectively. You can extend
from <classname>org.hibernate.envers.DefaultRevisionEntity</classname>, if you wish, to inherit all
these required behaviors.
</para>
<para>
Simply add the custom revision entity as you do your normal entities. Envers will "find it". Note
that it is an error for there to be multiple entities marked as
<interfacename>@org.hibernate.envers.RevisionEntity</interfacename>
</para>
</listitem>
<listitem>
<para>
Second, you need to tell Envers how to create instances of your revision entity which is handled
by the <methodname>newRevision</methodname> method of the
<interfacename>org.jboss.envers.RevisionListener</interfacename> interface.
</para>
<para>
You tell Envers your custom <interfacename>org.hibernate.envers.RevisionListener</interfacename>
implementation to use by specifying it on the
<interfacename>@org.hibernate.envers.RevisionEntity</interfacename> annotation, using the
<methodname>value</methodname> attribute.
</para>
</listitem>
</orderedlist>
<programlisting><![CDATA[@Entity
@RevisionEntity( MyCustomRevisionListener.class )
public class MyCustomRevisionEntity {
...
}
public class MyCustomRevisionListener implements RevisionListener {
public void newRevision(Object revisionEntity) {
( (MyCustomRevisionEntity) revisionEntity )...;
}
}
]]></programlisting>
<para>
An alternative method to using the <interfacename>org.hibernate.envers.RevisionListener</interfacename>
is to instead call the <methodname>getCurrentRevision</methodname> method of the
<interfacename>org.hibernate.envers.AuditReader</interfacename> interface to obtain the current revision,
and fill it with desired information. The method accepts a <literal>persist</literal> parameter indicating
whether the revision entity should be persisted prior to returning from this method. <literal>true</literal>
which will ensure the returned entity has access to its identifier value (revision number), but the revision
entity will be persisted regardless of whether there are any audited entities changed. <literal>false</literal>
means that the revision number will be <literal>null</literal>, but the revision entity will be persisted
only if some audited entities have changed.
</para>
<example>
<title>Example of storing username with revision</title>
<programlisting>
<filename>ExampleRevEntity.java</filename><![CDATA[package org.hibernate.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>
<programlisting>
<filename>ExampleListener.java</filename><![CDATA[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>
</example>
</section>
<section>
<title>Envers Schema</title>
<para>
For each audited entity (that is, for each entity containing at least one audited field), an audit table is
created. By default, the audit table's name is created by adding a "_AUD" suffix to the original table name,
but this can be overridden by specifying a different suffix/prefix in the configuration or per-entity using
the <interfacename>@org.hibernate.envers.AuditTable</interfacename> annotation.
</para>
<orderedlist>
<title>Audit table columns</title>
<listitem>
<para>
id of the original entity (this can be more then one column in the case of composite primary keys)
</para>
</listitem>
<listitem>
<para>
revision number - an integer. Matches to the revision number in the revision entity table.
</para>
</listitem>
<listitem>
<para>
revision type - a small integer
</para>
</listitem>
<listitem>
<para>
audited fields from the original entity
</para>
</listitem>
</orderedlist>
<para>
The primary key of the audit table is the combination of the original id of the entity and the revision
number - there can be at most one historic entry for a given entity instance at a given revision.
</para>
<para>
The current entity data is stored in the original table and in the audit table. This is a duplication of
data, however as this solution makes the query system much more powerful, and as memory is cheap, hopefully
this won't be a major drawback for the users. A row in the audit table with entity id ID, revision N and
data D means: entity with id ID has data D from revision N upwards. Hence, if we want to find an entity at
revision M, we have to search for a row in the audit table, which has the revision number smaller or equal
to M, but as large as possible. If no such row is found, or a row with a "deleted" marker is found, it means
that the entity didn't exist at that revision.
</para>
<para>
The "revision type" field can currently have three values: 0, 1, 2, which means ADD, MOD and DEL,
respectively. A row with a revision of type DEL will only contain the id of the entity and no data (all
fields NULL), as it only serves as a marker saying "this entity was deleted at that revision".
</para>
<para>
Additionally, there is a <term>revision entity</term> table which contains the information about the
global revision. By default the generated table is named <database class="table">REVINFO</database> and
contains just 2 columns: <database class="field">ID</database> and <database class="field">TIMESTAMP</database>.
A row is inserted into this table on each new revision, that is, on each commit of a transaction, which
changes audited data. The name of this table can be configured, the name of its columns as well as adding
additional columns can be achieved as discussed in <xref linkend="envers-revisionlog"/>.
</para>
<para>
While global revisions are a good way to provide correct auditing of relations, some people have pointed out
that this may be a bottleneck in systems, where data is very often modified. One viable solution is to
introduce an option to have an entity "locally revisioned", that is revisions would be created for it
independently. This wouldn't enable correct versioning of relations, but wouldn't also require the
<database class="table">REVINFO</database> table. Another possibility is to introduce a notion of
"revisioning groups": groups of entities which share revision numbering. Each such group would have to
consist of one or more strongly connected component of the graph induced by relations between entities.
Your opinions on the subject are very welcome on the forum! :)
</para>
</section>
</chapter>

View File

@ -6,7 +6,6 @@
<book>
<xi:include href="Book_Info.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<!-- <xi:include href="Chapter.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />-->
<xi:include href="Database_Access.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Transactions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Batch_Processing.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
@ -19,6 +18,7 @@
<xi:include href="Criteria.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Native_SQL.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="JMX.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Envers.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="appendix-Configuration_Properties.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Revision_History.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<index />

View File

@ -4,10 +4,102 @@
%BOOK_ENTITIES;
]>
<preface id="pref-Hibernate_Development_Guide-Preface">
<title>Preface</title>
<!-- <xi:include href="Common_Content/Conventions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Feedback.xml" xmlns:xi="http://www.w3.org/2001/XInclude"><xi:fallback xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="Common_Content/Feedback.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</xi:fallback>
</xi:include>-->
<title>Preface</title>
<para>
Working with both Object-Oriented software and Relational Databases can be cumbersome and time consuming.
Development costs are significantly higher due to a paradigm mismatch between how data is represented in
objects versus relational databases. Hibernate is an Object/Relational Mapping solution for Java environments.
The term Object/Relational Mapping refers to the technique of mapping data from an object model representation
to a relational data model representation (and visa versa). See
<ulink url="http://en.wikipedia.org/wiki/Object-relational_mapping"/> for a good high-level discussion.
</para>
<note>
<para>
While having a strong background in SQL is not required to use Hibernate, having a basic understanding of
the concepts can greatly help you understand Hibernate more fully and quickly. Probably the single
best background is an understanding of data modeling principles. You might want to consider these resources
as a good starting point:
<itemizedlist>
<listitem>
<para>
<ulink url="http://www.agiledata.org/essays/dataModeling101.html"/>
</para>
</listitem>
<listitem>
<para>
<ulink url="http://en.wikipedia.org/wiki/Data_modeling"/>
</para>
</listitem>
</itemizedlist>
</para>
</note>
<para>
Hibernate not only takes care of the mapping from Java classes to database tables (and from Java data types to
SQL data types), but also provides data query and retrieval facilities. It can significantly reduce
development time otherwise spent with manual data handling in SQL and JDBC. Hibernates design goal is to
relieve the developer from 95% of common data persistence-related programming tasks by eliminating the need for
manual, hand-crafted data processing using SQL and JDBC. However, unlike many other persistence solutions,
Hibernate does not hide the power of SQL from you and guarantees that your investment in relational technology
and knowledge is as valid as always.
</para>
<para>
Hibernate may not be the best solution for data-centric applications that only use stored-procedures to
implement the business logic in the database, it is most useful with object-oriented domain models and business
logic in the Java-based middle-tier. However, Hibernate can certainly help you to remove or encapsulate
vendor-specific SQL code and will help with the common task of result set translation from a tabular
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.
</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Getting Started Guide</title>
<para>
New users may want to first look through the
<citetitle pubwork="book">Hibernate Getting Started Guide</citetitle> for basic information as well as
tutorials. Even seasoned veterans may want to considering perusing the sections pertaining to
build artifacts for any changes.
</para>
</section>
</preface>

View File

@ -1,95 +0,0 @@
<?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>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-parent</artifactId>
<version>3.6.0-SNAPSHOT</version>
<relativePath>../../parent/pom.xml</relativePath>
</parent>
<artifactId>devguide</artifactId>
<packaging>jdocbook</packaging>
<name>Hibernate Developer Guide</name>
<description>A guide for developers using Hibernate</description>
<properties>
<!-- Skip artifact deployment -->
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.jboss.maven.plugins</groupId>
<artifactId>maven-jdocbook-plugin</artifactId>
<executions>
<execution>
<!--
here we are attaching the translate goal so that the translations are processed
before compilation so that the translated XML is also transformed during
generation
-->
<phase>process-resources</phase>
<goals>
<goal>translate</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDocumentName>Hibernate_Developer_Guide.xml</sourceDocumentName>
<masterTranslation>en-US</masterTranslation>
<translations>
<!--
<translation>de-DE</translation>
<translation>es-ES</translation>
<translation>fr-FR</translation>
<translation>ja-JP</translation>
<translation>ko-KR</translation>
<translation>pt-BR</translation>
<translation>zh-CN</translation>
-->
</translations>
<imageResource>
<directory>${basedir}/src/main/docbook/en-US</directory>
<excludes>
<exclude>*.xml</exclude>
<exclude>**/*.xml</exclude>
<exclude>*.zargo</exclude>
<exclude>**/*.zargo</exclude>
</excludes>
</imageResource>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,193 +0,0 @@
<?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
-->
<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
]>
<authorgroup>
<author>
<firstname>Gavin</firstname>
<surname>King</surname>
</author>
<author>
<firstname>Christian</firstname>
<surname>Bauer</surname>
</author>
<author>
<firstname>Max</firstname>
<othername>Rydahl</othername>
<surname>Andersen</surname>
</author>
<author>
<firstname>Emmanuel</firstname>
<surname>Bernard</surname>
</author>
<author>
<firstname>Steve</firstname>
<surname>Ebersole</surname>
</author>
<author>
<firstname>Hardy</firstname>
<surname>Ferentschik</surname>
</author>
<othercredit>
<firstname>James</firstname>
<surname>Cobb</surname>
<affiliation>
<shortaffil>Graphic Design</shortaffil>
</affiliation>
</othercredit>
<othercredit>
<firstname>Cheyenne</firstname>
<surname>Weaver</surname>
<affiliation>
<shortaffil>Graphic Design</shortaffil>
</affiliation>
</othercredit>
<!--
#######################################################################
# Spanish
#######################################################################
-->
<othercredit class="translator" lang="es-ES">
<othername><![CDATA[Bernardo Antonio Buffa Colom&#x00e9]]></othername>
<email>kreimer@bbs.frc.utn.edu.ar</email>
</othercredit>
<!--
#######################################################################
# French
#######################################################################
-->
<othercredit class="translator" lang="fr-FR">
<firstname>Vincent</firstname>
<surname>Ricard</surname>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Sebastien</firstname>
<surname>Cesbron</surname>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Michael</firstname>
<surname>Courcy</surname>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Vincent</firstname>
<surname>Giguère</surname>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Baptiste</firstname>
<surname>Mathus</surname>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Emmanuel</firstname>
<surname>Bernard</surname>
</othercredit>
<othercredit class="translator" lang="fr-FR">
<firstname>Anthony</firstname>
<surname>Patricio</surname>
</othercredit>
<!--
#######################################################################
# Portugese
#######################################################################
-->
<othercredit class="translator" lang="pt-BR">
<firstname>Alvaro</firstname>
<surname>Netto</surname>
<email>alvaronetto@cetip.com.br</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Anderson</firstname>
<surname>Braulio</surname>
<email>andersonbraulio@gmail.com</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Daniel Vieira</firstname>
<surname>Costa</surname>
<email>danielvc@gmail.com</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Francisco</firstname>
<surname>gamarra</surname>
<email>francisco.gamarra@gmail.com</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Gamarra</firstname>
<email>mauricio.gamarra@gmail.com</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Luiz Carlos</firstname>
<surname>Rodrigues</surname>
<email>luizcarlos_rodrigues@yahoo.com.br</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Marcel</firstname>
<surname>Castelo</surname>
<email>marcel.castelo@gmail.com</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Paulo</firstname>
<surname>César</surname>
<email>paulocol@gmail.com</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Pablo L.</firstname>
<surname>de Miranda</surname>
<email>pablolmiranda@gmail.com</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Renato</firstname>
<surname>Deggau</surname>
<email>rdeggau@gmail.com</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Rogério</firstname>
<surname>Araújo</surname>
<email>rgildoaraujo@yahoo.com.br</email>
</othercredit>
<othercredit class="translator" lang="pt-BR">
<firstname>Wanderson</firstname>
<surname>Siqueira</surname>
<email>wandersonxs@gmail.com</email>
</othercredit>
<!--
#######################################################################
# Chinese
#######################################################################
-->
<othercredit class="translator" lang="zh-CN">
<firstname>Cao</firstname>
<surname>Xiaogang</surname>
<affiliation>
<orgname>RedSaga</orgname>
</affiliation>
<contrib>Translation Lead</contrib>
<email>caoxg@yahoo.com</email>
</othercredit>
</authorgroup>

View File

@ -1,54 +0,0 @@
<?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
-->
<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "Hibernate_Developer_Guide.ent">
%BOOK_ENTITIES;
]>
<bookinfo id="Hibernate_Developer_Guide">
<title>Hibernate Developer Guide</title>
<releaseinfo>&version;</releaseinfo>
<edition>1.0</edition>
<pubsnumber>1</pubsnumber>
<productname>JBoss Hibernate Core</productname>
<productnumber>&version;</productnumber>
<pubdate>&today;</pubdate>
<issuenum>1</issuenum>
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/hibernate_logo_a.png" align="center" />
</imageobject>
<imageobject role="html">
<imagedata fileref="images/hibernate_logo_a.png" depth="3cm" />
</imageobject>
</mediaobject>
<copyright>
<year>&copyrightYear;</year>
<holder>&copyrightHolder;</holder>
</copyright>
<xi:include href="Author_Group.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</bookinfo>

View File

@ -1,5 +0,0 @@
<!ENTITY version "WORKING">
<!ENTITY today "TODAY">
<!ENTITY copyrightYear "2004">
<!ENTITY copyrightHolder "Red Hat, Inc.">
<!ENTITY semi ";">

View File

@ -1,14 +0,0 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "Hibernate_Developer_Guide.ent">
%BOOK_ENTITIES;
]>
<book>
<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" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="content/database.xml" />
</book>

View File

@ -1,191 +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-dev-database">
<title>Database Access</title>
<section id="hibernate-dev-database-connect">
<title>JDBC Connections</title>
<para>
Hibernate understands how to connect to a database through an interface
<interfacename>org.hibernate.connection.ConnectionProvider</interfacename>. While
<interfacename>org.hibernate.connection.ConnectionProvider</interfacename> is considered an extension SPI,
Hibernate comes with a number of built-in providers.
</para>
<section id="hibernate-dev-database-connect-pools">
<title>Using connection pooling</title>
<para>
The built-in connection pooling based providers all require the following settings
</para>
<variablelist>
<varlistentry>
<term><property>hibernate.connection.driver_class</property></term>
<listitem>
<para>
Names the <interfacename>java.sql.Driver</interfacename> implementation class from your JDBC
provider.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>hibernate.connection.url</property></term>
<listitem>
<para>
The JDBC connection url. See your JDBC provider's documentation for details and examples.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>hibernate.connection.username</property></term>
<listitem>
<para>
The name of the user to use when opening a JDBC <interfacename>java.sql.Connection</interfacename>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>hibernate.connection.password</property></term>
<listitem>
<para>
The password associated with the provided username.
</para>
</listitem>
</varlistentry>
</variablelist>
<section id="hibernate-dev-database-connect-pools-hibernate">
<title>Using Hibernate's built-in connection pooling</title>
<warning>
<para>
The built-in Hibernate connection pool is not intended for production use. It lacks several
features found on any decent connection pool. However, it can be quite useful to get started
and in unit testing.
</para>
</warning>
<para>
The only additional supported setting for the built-in pooling is the
<property>hibernate.connection.pool_size</property> setting which tells the pool how many
connections maximum it can keep in the pool.
</para>
</section>
<section id="hibernate-dev-database-connect-pools-c3p0">
<title>Using c3p0 for connection pooling</title>
<para>
<!-- todo : what exactly needs discussed here? -->
To be continued...
</para>
</section>
<section id="hibernate-dev-database-connect-pools-proxool">
<title>Using proxool for connection pooling</title>
<para>
<!-- todo : what exactly needs discussed here? -->
To be continued...
</para>
</section>
</section>
<section id="hibernate-dev-database-connect-dataSource">
<title>Using <interfacename>javax.sql.DataSource</interfacename></title>
<!-- todo : centralized discussion of JNDI properties -->
<para>
Hibernate can also use a <interfacename>javax.sql.DataSource</interfacename> to obtain
connections. To do so, Hibernate expects to be able to locate the
<interfacename>javax.sql.DataSource</interfacename> in <literal>JNDI</literal>. The
<property>hibernate.connection.datasource</property> setting tells Hibernate the <literal>JNDI</literal>
namespace at which it can find the the <interfacename>javax.sql.DataSource</interfacename>.
</para>
<para>
Generally speaking a <interfacename>javax.sql.DataSource</interfacename> is configured to connect to
the database using a single set of credentials (username/password). Sometimes, however, the
<interfacename>javax.sql.DataSource</interfacename> is set up so that the credentials have to be
used to obtain a <interfacename>java.sql.Connection</interfacename> from it. In these cases
applications would specify the credentials via the <property>hibernate.connection.username</property>
and <property>hibernate.connection.password</property> settings, which Hibernate would pass along to the
<interfacename>javax.sql.DataSource</interfacename> when obtaining a
<interfacename>java.sql.Connection</interfacename> from it.
</para>
</section>
</section>
<section id="hibernate-dev-database-dialect">
<title>Database Dialects</title>
<para>
A <firstterm><phrase>Dialect</phrase></firstterm> informs Hibernate of the capabilities of the
underlying database. This role is fulfilled by an instance of a
<classname>org.hibernate.dialect.Dialect</classname> subclass. The Dialect is one of the most important
pieces of information given to the Hibernate <interfacename>org.hibernate.Sessionfactory</interfacename>
during startup as it allows Hibernate to properly plan how it needs to communicate with the database.
</para>
<section id="hibernate-dev-database-dialect-config">
<title>Specifying the Dialect to use</title>
<para>
The developer may manually specify the Dialect to use by setting the
<property>hibernate.dialect</property> configuration property to the name of the specific
<classname>org.hibernate.dialect.Dialect</classname> class to use.
</para>
</section>
<section id="hibernate-dev-database-dialect-resolution">
<title>Dialect resolution</title>
<para>
Assuming a <interfacename>org.hibernate.connection.ConnectionProvider</interfacename> has been
set up according to <xref linkend="hibernate-dev-database-connect"/> then Hibernate will attempt
to automatically determine the Dialect to use based on the
<interfacename>java.sql.DatabaseMetaData</interfacename> reported by a
<interfacename>java.sql.Connection</interfacename> obtained from that
<interfacename>org.hibernate.connection.ConnectionProvider</interfacename>.
</para>
<para>
This functionality is provided by a series of
<interfacename>org.hibernate.dialect.resolver.DialectResolver</interfacename> instances registered
with Hibernate internally. Hibernate comes with a standard set of recognitions. If your application
requires extra Dialect resolution capabilities, it would simply register a custom implementation
of <interfacename>org.hibernate.dialect.resolver.DialectResolver</interfacename> as follows
</para>
<example id="hibernate-dev-database-dialect-resolution-registration">
<title>Registering a custom <interfacename>org.hibernate.dialect.resolver.DialectResolver</interfacename></title>
<programlisting role="JAVA"><![CDATA[
org.hibernate.dialect.resolver.DialectFactory.registerDialectResolver( "org.hibernate.example.CustomDialectResolver" );
]]></programlisting>
</example>
<para>
Registered <interfacename>org.hibernate.dialect.resolver.DialectResolver</interfacename> are
<emphasis>prepended</emphasis> to an internal list of resolvers, so they take precedence
before any already registered resolvers including the standard one.
</para>
</section>
<section id="hibernate-dev-database-dialect-custom">
<title>Custom Dialects</title>
<para>
It is sometimes necessary for developers to write a custom Dialect for Hibernate to use. Generally
this is as simple as selecting a particular <classname>org.hibernate.dialect.Dialect</classname>
implementation that is closest to your needs and subclassing it and overriding where necessary.
</para>
<para>
Custom dialects may be manually specified as outlined in
<xref linkend="hibernate-dev-database-dialect-config"/> as well as registered through a resolver as
outlined in <xref linkend="hibernate-dev-database-dialect-resolution-registration"/>.
</para>
</section>
</section>
<section id="hiberate-dev-database-schema">
<title>Database Schema</title>
<para>
<!-- todo : what exactly needs discussed here? -->
To be continued...
</para>
</section>
</chapter>

View File

@ -1,133 +0,0 @@
<?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
-->
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "../Hibernate_Developer_Guide.ent">
%BOOK_ENTITIES;
]>
<preface id="hibernate-gsg-preface">
<title>Preface</title>
<!--
NOTE : This duplicates a lot of the information in the manual preface. This is a great example of where the
"content reuse" capabilities of DITA could be leveraged.
-->
<para>
Working with both Object-Oriented software and Relational Databases can be cumbersome and time consuming.
Development costs are significantly higher due to a paradigm mismatch between how data is represented in
objects versus relational databases. Hibernate is an Object/Relational Mapping solution for Java environments.
The term Object/Relational Mapping refers to the technique of mapping data from an object model representation
to a relational data model representation (and visa versa). See
<ulink url="http://en.wikipedia.org/wiki/Object-relational_mapping"/> for a good high-level discussion.
</para>
<note>
<para>
While having a strong background in SQL is not required to use Hibernate, having a basic understanding of
the concepts can greatly help you understand Hibernate more fully and quickly. Probably the single
best background is an understanding of data modeling principles. You might want to consider these resources
as a good starting point:
<itemizedlist>
<listitem>
<para>
<ulink url="http://www.agiledata.org/essays/dataModeling101.html"/>
</para>
</listitem>
<listitem>
<para>
<ulink url="http://en.wikipedia.org/wiki/Data_modeling"/>
</para>
</listitem>
</itemizedlist>
</para>
</note>
<para>
Hibernate not only takes care of the mapping from Java classes to database tables (and from Java data types to
SQL data types), but also provides data query and retrieval facilities. It can significantly reduce
development time otherwise spent with manual data handling in SQL and JDBC. Hibernates design goal is to
relieve the developer from 95% of common data persistence-related programming tasks by eliminating the need for
manual, hand-crafted data processing using SQL and JDBC. However, unlike many other persistence solutions,
Hibernate does not hide the power of SQL from you and guarantees that your investment in relational technology
and knowledge is as valid as always.
</para>
<para>
Hibernate may not be the best solution for data-centric applications that only use stored-procedures to
implement the business logic in the database, it is most useful with object-oriented domain models and business
logic in the Java-based middle-tier. However, Hibernate can certainly help you to remove or encapsulate
vendor-specific SQL code and will help with the common task of result set translation from a tabular
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>Getting Started Guide</title>
<para>
New users may want to first look through the
<citetitle pubwork="book">Hibernate Getting Started Guide</citetitle> for basic information as well as
tutorials. Even seasoned veterans may want to considering perusing the sections pertaining to
build artifacts for any changes.
</para>
</section>
</preface>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1,176 +0,0 @@
THE HIBERNATE DOCUMENTATION
christian@hibernate.org
COPYRIGHT NOTICE: This documentation system and all its source files are
licensed under the GNU Lesser Public License (LGPL). Authors and translators
retain the copyright of their work. All font and other build files (the DocBook
system) are property of their respective copyright holders. Some of the files
(especially font files) might require a license from the respective vendor; you
are responsible to check and obtain these licenses as necessary before you use
and/or distribute these files.
Preface
The Hibernate documentation is a modular documentation, it uses
various XML files (written with the DocBook DTD) and a Java-based
build process to generate HTML and PDF output. Use a simple text
editor with XML support, such as JEdit, to edit the source files. You
will need Java and Ant installed for the output generation. The toolset
is Java only and should work on any operating system.
Note: Always use 4 spaces to indent, no tabstops (code examples will
be broken otherwise).
1. How to get it
Check out a copy of Hibernate from the repository. A regular
Hibernate download will not contain the build process for the
documentation, only the PDF/HTML output, use the repository!
See http://www.hibernate.org/Download/DownloadOverview
2. Working on the original language
The original and master language is English, hence the "en" subdirectory
in /doc/reference/ is authorative. We use "id" and "revision" attributes on
XML elements to track changes. Here are the rules, they are mandatory:
2a. Changing existing content involves an update of the "revision" of the XML
element you are working on (e.g. a <sect1>, <sect2> or even a <para>).
If a <sect1> has a revision="1", you update it to "2" after updating the
content in that section.
You can also add a revision attribute to an element if there is none,
start with revision="1". You should not add a revision attribute to each
paragraph, try to only add/use revision attributes to sections. You can'
t add a revision attribute to elements without an "id" attribute!
2b. Adding new content involves adding new elements (even new files), such
as <sect1>, <para> and so on. Any new element (or its new parent element)
needs an "id" attribute if the new content is to be included in the change
tracking. If you add a section, give it a unique short text
identifer, look at the parent element's identifier for the common prefix.
2c. Deleting content involves removing old elements. Just remove them and
make sure that the parent elements revision is updated, if the removed
element did not itself have an identifer and a revision. If you remove an
element with its own identifier, everything is fine and no other changes are
necessary.
3. Starting a new language
If you start a translation for a new language, you have to copy
the default language (English) and start an initial translation.
3a. First, duplicate the default language "en" by duplicating the directory
/doc/reference/en. For example, a new German translation
will be a copy of that directory in /doc/reference/de. We use the ISO
codes to name the language subdirectories.
3b. You also have to add your new language to the language build file,
/doc/reference/build.xml. Look for the lines that have a "TRANSLATOR"
comment and duplicate them. Change the default "en" to your language
code, every language listed here will be included in both the PDF/HTML
generation and the revision diff change tracking reports (discussed later).
4. The initial translation
If you just copied the default language, start translating the DocBook
XML modules and illustrations in the new language subdirectory. For
example, all modules for German would be in /doc/reference/de/modules
and all illustrations in /doc/reference/de/images, note that you also have
to translate the master.xml in your language subdirectory.
The initial translation is straightforward: Translate all modules and
all illustrations, but don't add any files, don't add any new XML elements
(like a section or a chapter, not even a paragraph). Simply translate
sentence by sentence. This is very important.
Note that every DocBook XML file needs an encoding, specific to a
language. Add a line like this at the top of every file, if it doesn't exist:
<?xml version='1.0' encoding="iso-8859-1"?>
You can use UTF-8 or any other character set, please experiment with
the builds to see what works for you.
If you need a new section or paragraph, because your translation requires
more explanation, you can add it if you also add an "id" and a "revision"
to that new section or paragraph.
For example, if you add a new <para> element to the existing document,
give it an identifier, a short unique string that extends the identifier
string of the parent element: <para id="queryhql-projection-specialnote">
would be a special paragraph in the <sect1 id="queryhql-projection">
section in the chapter <chapter id="queryhql">.
Never add a new element in a translated version without also adding a new
unique identifier value! Also, you have to mark this new element as "only
relevant in the translated version". Simply set the "revision" attribute of
your new element to "-1". For example, set the previously created
paragraph to "only relevant in the translation" by declaring
<para id="queryhql-projection-specialnote" revision="-1">.
Changes to that paragraph will not be tracked, it is your responsibility to
watch out for neccessary updates. Any element with revision="-1" will not be
tracked.
5. Updating translated documentation
Translators get updates by updating their working directory from the
repository. As a translator you will get an e-mail from us when translation
is required, you can then update your copy. Or, subscribe to the commit
mailing list to get all updates automatically.
The documentation tools can generate a report after you updated
from the repository and show you what needs to be translated and/or removed
in your local translation copy. To generate that report, run "ant all.revdiff"
in the doc/reference/ subdirectory. Click on the generated HTML report
file for your language and you will see what has to be updated and/or
removed.
If the report indicates that content in the original has been removed,
simply remove the identified XML element from your language modules.
If the report detects a new revision, open the file that has been updated
in your translation, find the identified XML element and update/translate
its contents. Important: Make sure you also update the "revision"
attribute of that XML element by setting it to the same version as in
the original file, hence both the original XML file and your translated
file should have the same revision number for all elements. If an
XML element in your translation doesn't have a revision, but the original
file has, add a new "revision" attribute to your XML element.
The HTML report shows the identifiers and revisions for both the original
and the translated files, use it to compare.
Rerun the "ant all.revdiff" report generation as often as you like until
no more differences are detected. You should always try to get your
copy clean, with all updated revisions and all identified elements
synchronzied.
6. Committing a translation
All translators will be asked to submit their translated versions from
time to time. This will be a manual process, you will get an e-mail from
the Hibernate team and simply send your language subdirectory as
a ZIP file to us. It will then be integrated in the main Hibernate
distribution and on the website. Or, you can contact us for commit access
to the repository, where you can maintain a translation directly.
7. Generating PDF and HTML output
The documentation is generated with the target 'ant all.doc'.
To build the reference docs for a particular language only, use
"ant -Dlang=en", for example, and call either lang.all, lang.docpdf,
lang.dochtml, or lang.dochtmlsingle for the target of your choice.
You can also call lang.section-check to track down missing identifiers in
a particular language, or you can call lang.revdiff to get a difference
report for a particular language, compared with the English reference.

View File

@ -1,61 +0,0 @@
<?xml version='1.0' encoding="UTF-8"?>
<!--
~ Copyright (c) 2008, Red Hat Middleware, LLC. All rights reserved.
~
~ 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, v. 2.1. This program is distributed in the
~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
~ distribution; if not, write to the Free Software Foundation, Inc.,
~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
~
~ Red Hat Author(s): Brian Stansberry
-->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY versionNumber "3.5.0.alpha1">
<!ENTITY copyrightYear "2009">
<!ENTITY copyrightHolder "Red Hat, Inc.">
]>
<book>
<bookinfo>
<title>HIBERNATE - Relational Persistence for Idiomatic Java</title>
<subtitle>Using JBoss Cache as a Hibernate Second Level Cache</subtitle>
<releaseinfo>&versionNumber;</releaseinfo>
<productnumber>&versionNumber;</productnumber>
<!--<issuenum>1</issuenum>-->
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/hibernate_logo_a.png" align="center" />
</imageobject>
<imageobject role="html">
<imagedata fileref="images/hibernate_logo_a.png" depth="3cm" />
</imageobject>
</mediaobject>
<copyright>
<year>&copyrightYear;</year>
<holder>&copyrightHolder;</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/introduction.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/concepts.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/eviction.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</book>

View File

@ -1,293 +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">
<!--
~ Copyright (c) 2008, Red Hat Middleware, LLC. All rights reserved.
~
~ 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, v. 2.1. This program is distributed in the
~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
~ distribution; if not, write to the Free Software Foundation, Inc.,
~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
~
~ Red Hat Author(s): Brian Stansberry
-->
<chapter id="architecture">
<title>Architecture</title>
<para>
We've now gone through all the main concepts and the configuration
details; now we'll look a bit under the covers to understand a bit
more about the architectural design of the Hibernate/JBoss Cache
integration. Readers can skip this chapter if they aren't interested
in a look under the covers.
</para>
<sect1 id="architecture-interface" revision="1">
<title>Hibernate Interface to the Caching Subsystem</title>
<para>
The rest of Hibernate interacts with the Second Level Cache subsystem
via the <literal>org.hibernate.cache.RegionFactory</literal> interface.
What implementation of the interface is used is determined by the
value of the <literal>hibernate.cache.region.factory_class</literal>
configuration property. The interface itself is straightforward:
</para>
<programlisting><![CDATA[void start(Settings settings, Properties properties)
throws CacheException;
void stop();
boolean isMinimalPutsEnabledByDefault();
long nextTimestamp();
EntityRegion buildEntityRegion(String regionName,
Properties properties,
CacheDataDescription metadata)
throws CacheException;
CollectionRegion buildCollectionRegion(String regionName,
Properties properties,
CacheDataDescription cdd)
throws CacheException;
QueryResultsRegion buildQueryResultsRegion(String regionName,
Properties properties)
throws CacheException;
TimestampsRegion buildTimestampsRegion(String regionName,
Properties properties)
throws CacheException;]]></programlisting>
<itemizedlist>
<listitem>
<para>
The <literal>start</literal> method is invoked during
<literal>SessionFactory</literal> startup and allows the region
factory implementation to access all the configuration settings
and initialize itself. The <literal>stop</literal> method is
invoked during <literal>SessionFactory</literal> shutdown.
</para>
</listitem>
<listitem>
<para>
The various <literal>build***Region</literal> methods are invoked as
Hibernate detects it needs to cache different data. Hibernate can
invoke these methods multiple times, with different
<literal>regionName</literal> values; each call results in the
establishment of a separate area in the underlying JBoss Cache
instance(s). For example, if an application includes an
entity class <literal>org.example.Order</literal> and another entity
class <literal>org.example.LineItem</literal>, you would see two
calls to <literal>buildEntityRegion</literal>, one for the
<literal>Order</literal> class and one for the
<literal>LineItem</literal> class. (Note that it is possible, and
recommended, to configure one or more shared regions for entities,
collections and queries. See <xref linkend="eviction-organization"/>
for some examples.)
</para>
</listitem>
<listitem>
<para>
For each call to a <literal>build***Region</literal> method, the
region factory returns a region object implementing the
<literal>EntityRegion</literal>, <literal>CollectionRegion</literal>,
<literal>QueryResultsRegion</literal> or <literal>TimestampsRegion</literal>
interface. Each interface specifies the needed semantics for
caching the relevant type of data. Thereafter, the Hibernate core
invokes on that region object to manage reading and writing data
in the cache.
</para>
</listitem>
</itemizedlist>
<para>
Next, we'll look at the architecture of how the JBoss Cache integration
implements these interfaces, first in the case where a single JBoss
Cache instance is used, next in the case where multiple instances are
desired.
</para>
</sect1>
<sect1 id="architecture-single-cache" revision="1">
<title>Single JBoss Cache Instance Architecture</title>
<para>
The following diagram illustrates the key elements involved when
a single JBoss Cache instance is used:
</para>
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/single-cache.png" format="PNG" align="center" />
</imageobject>
<imageobject role="html">
<imagedata fileref="images/single-cache.png" format="PNG" align="center" />
</imageobject>
</mediaobject>
<itemizedlist>
<listitem>
<para>
For the single cache case, the user should specify
<literal>SharedJBossCacheRegionFactory</literal> as their
<literal>hibernate.cache.region.factory_class</literal>.
</para>
</listitem>
<listitem>
<para>As part of its startup process, the region factory delegates
responsibility for providing JBoss Cache instances to an
implementation of the
<literal>org.hibernate.cache.jbc.CacheInstanceManager</literal>
interface. The region factory separately requests a JBoss Cache
instance for entities, one for collections, one for queries and one
for timestamps. Whether the <literal>CacheInstanceManager</literal>
provides the same underlying JBoss Cache instance for each
request or provides multiple caches is an implementation detail
of the <literal>CacheInstanceManager</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>SharedJBossCacheRegionFactory</literal> creates an
instance of <literal>SharedCacheInstanceManager</literal> as
its <literal>CacheInstanceManager</literal>.
<literal>SharedCacheInstanceManager</literal> uses the JBoss Cache
configuration file specified by the user to create a single
<literal>org.jboss.cache.Cache</literal> instance, and provides
that same instance to the region factory when it requests the
cache for entities, collections, queries and timestamps.
<literal>SharedCacheInstanceManager</literal> also creates an
<literal>org.jgroups.ChannelFactory</literal> and passes it to
the <literal>Cache</literal>. The <literal>ChannelFactory</literal>
provides the cache with the <literal>org.jgroups.Channel</literal>
it uses for intra-cluster communication.
</para>
</listitem>
<listitem>
<para>
At this point, the region factory has a reference to a cache
for entities, a reference to a cache for collections, one for
queries and one for timestamps. In this particular case, each
reference points to the same underlying <literal>Cache</literal>
instance. When core Hibernate invokes the
<literal>buildEntityRegion</literal> operation on the region
factory, it instantiates an implementation of the
<literal>EntityRegion</literal> interface that knows how to
interface with JBoss Cache, passing it a reference to its
entity cache. Same thing happens for collections, etc.
</para>
</listitem>
<listitem>
<para>
Core Hibernate invokes on the <literal>EntityRegion</literal>,
which in turn invokes read and write operations on the underlying
JBoss Cache. The cache uses its <literal>Channel</literal> to
propagate changes to its peers in the cluster.
</para>
</listitem>
<listitem>
<para>
When the <literal>SessionFactory</literal> shuts down, it
invokes <literal>stop()</literal> on the region factory, which
in turn ensures that the JBoss Cache instance is stopped and
destroyed (which in turn closes the JGroups channel).
</para>
</listitem>
</itemizedlist>
</sect1>
<sect1 id="architecture-cache-per-type" revision="1">
<title>Multiple JBoss Cache Instance Architecture</title>
<para>
The situation when multiple JBoss Cache instances are used is very
similar to the single cache case:
</para>
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/multi-cache.png" format="PNG" align="center" />
</imageobject>
<imageobject role="html">
<imagedata fileref="images/multi-cache.png" format="PNG" align="center" />
</imageobject>
</mediaobject>
<itemizedlist>
<listitem>
<para>
Here the user should specify
<literal>MultiplexedJBossCacheRegionFactory</literal> as their
<literal>hibernate.cache.region.factory_class</literal>. The
<literal>MultiplexedJBossCacheRegionFactory</literal> shares
almost all its code with <literal>SharedJBossCacheRegionFactory</literal>;
the main difference is it constructs a different <literal>CacheInstanceManager</literal>
implementation -- the <literal>MultiplexedCacheInstanceManager</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>MultiplexedCacheInstanceManager</literal> differs from
<literal>SharedCacheInstanceManager</literal> in that it does
not directly instantiate a cache. Rather, it creates an
instance of <literal>org.jboss.cache.CacheManager</literal>,
providing it with a <literal>ChannelFactory</literal> and the
location of the user-specified cache configuration file. The
<literal>CacheManager</literal> parses the configuration file.
</para>
</listitem>
<listitem>
<para>
<literal>MultiplexedCacheInstanceManager</literal> analyzes
Hibernate's configuration to determine the name of the desired
cache configuration for entities, collections, queries and
timestamps. See <xref linkend="sessionfactory-multiplexed"/> for
details. It then asks its <literal>CacheManager</literal> to
provide each needed cache. In the diagram, two different caches are needed:
</para>
<itemizedlist>
<listitem>
<para>One, using the "optimistic-entity" configuration,
that is used for entities, collections and queries
</para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para>Another, with the "timestamps-cache" configuration,
that is used for timestamps.
</para>
</listitem>
</itemizedlist>
<para>
Both the "optimistic-entity" configuration and the "timestamps-cache"
configuration specify the use of the "udp" JGroups channel
configuration, so the <literal>CacheManager</literal>'s
<literal>ChannelFactory</literal> will ensure that they share
the underlying JGroups resources.
</para>
</listitem>
<listitem>
<para>
The way the region factory creates regions is exactly the same
as in the single JBoss Cache case; the only difference is the
region factory's internal reference to its timestamps cache
now points to a different cache object from the entity, collection
and query cache references.
</para>
</listitem>
</itemizedlist>
</sect1>
</chapter>

View File

@ -1,663 +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">
<!--
~ Copyright (c) 2009, Red Hat, Inc. All rights reserved.
~
~ 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, v. 2.1. This program is distributed in the
~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
~ distribution; if not, write to the Free Software Foundation, Inc.,
~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
~
~ Red Hat Author(s): Brian Stansberry
-->
<chapter id="eviction">
<title>Cache Eviction</title>
<sect1 id="eviction-overview" revision="1">
<title>Overview</title>
<para>
<emphasis>Eviction</emphasis> refers to the process by which old,
relatively unused, or excessively voluminous data can be dropped
from the cache, allowing the cache to remain within a memory budget.
Generally, applications that use the Second Level Cache should
configure eviction, unless only a relatively small amount of
reference data is cached. This chapter provides a brief overview
of how JBoss Cache eviction works, and then explains how to configure
eviction to effectively manage the data stored in a Hibernate Second
Level Cache. A basic understanding of JBoss Cache eviction and of
concepts like FQNs is assumed; see the <emphasis>JBoss Cache User Guide</emphasis>
for more information.
</para>
<sect2 id="eviction-overview-process" revision="1">
<title>The Eviction Process</title>
<para>
The JBoss Cache eviction process is fairly straightforward. Whenever
a node in a cache is read or written to, added or removed, the cache
finds the <emphasis>eviction region</emphasis> (see below) that
contains the node and passes an <emphasis>eviction event</emphasis>
object to the <emphasis>eviction policy</emphasis> (see below)
associated with the region. The eviction policy uses the stream of
events it receives to track activity in the region. Periodically,
a background thread runs and contacts each region's eviction
policy. The policy uses its knowledge of the activity in the region,
along with any configuration it was provided at startup, to determine
which if any cache nodes should be evicted from memory. It then
tells the cache to evict those nodes. Evicting a node means
dropping it from the cache's in-memory state. The eviction only
occurs on that cache instance; there is no cluster-wide eviction.
</para>
<para>
An important point to understand is that eviction proceeds
independently on each peer in the cluster, with what gets
evicted depending on the activity on that peer. There is no
"global eviction" where JBoss Cache removes a piece of data in
every peer in the cluster in order to keep memory usage inside
a budget. The Hibernate/JBC integration layer may remove some
data globally, but that isn't done for the kind of memory
management reasons we're discussing in this chapter.
</para>
<para>
An effect of this is that even if a cache is configured for
replication, if eviction is enabled the contents of a cache will
be different between peers in the cluster; some may have evicted
some data, while others will have evicted different data. What
gets evicted is driven by what data is accessed by users on each
peer.
</para>
<para>
Controlling when data is evicted from the cache is a matter
of setting up appropriate eviction regions and configuring
appropriate eviction policies for each region.
</para>
</sect2>
<sect2 id="eviction-overview-regions" revision="1">
<title>Eviction Regions</title>
<para>
JBoss Cache stores its data in a set of nodes organized in a tree
structure. An eviction region is a just a portion of the tree
to which an eviction policy has been assigned. The name of the
region is the FQN of the topmost node in that portion of the tree.
An eviction configuration always needs to include a special region
named <literal>_default_</literal>; this region is rooted in the
root node of the tree and includes all nodes not covered by
other regions.
</para>
<para>
It's possible to define regions that overlap. In other words, one
region can be defined for <emphasis>/a/b/c</emphasis>, and another
defined for <emphasis>/a/b/c/d</emphasis> (which is just the
<emphasis>d</emphasis> subtree of the <emphasis>/a/b/c</emphasis>
sub-tree). The algorithm that assigns eviction events to eviction
regions handles scenarios like this consistently by always choosing
the first region it encounters. So, if the algorithm needed to
decide how to handle an event affecting <emphasis>/a/b/c/d/e</emphasis>,
it would start from there and work its way up the tree until it
hits the first defined region - in this case <emphasis>/a/b/c/d</emphasis>.
</para>
</sect2>
<sect2 id="eviction-overview-policies" revision="1">
<title>Eviction Policies</title>
<para>
An <emphasis>Eviction Policy</emphasis> is a class that knows how
to handle eviction events to track the activity in its region.
It may have a specialized set of configuration properties that
give it rules for when a particular node in the region should be
evicted. It can then use that configuration and its knowledge of
activity in the region to to determine what nodes to evict.
</para>
<para>
JBoss Cache ships with a number of eviction policies. See the
<emphasis>JBoss Cache User Guide</emphasis> for a discussion of
all of them. Here we are going to focus on just two.
</para>
<sect3 id="eviction-overview-policies-lru" revision="1">
<title>The <literal>LRUPolicy</literal></title>
<para>
The <literal>org.jboss.cache.eviction.LRUPolicy</literal> evicts
nodes that have been Least Recently Used. It has the following
configuration parameters:
</para>
<itemizedlist>
<listitem>
<literal>maxNodes</literal>
- This is the maximum number of nodes allowed in this region.
0 denotes no limit. If the region has more nodes than this,
the least recently used nodes will be evicted until the number
of nodes equals this limit.
</listitem>
<listitem>
<literal>timeToLiveSeconds</literal>
- The amount of time a node is not written to or read (in seconds)
before the node should be evicted. 0 denotes no limit. Nodes that
exceed this limit will be evicted whether or not a
<literal>maxNodes</literal> limit has been breached.
</listitem>
<listitem>
<literal>maxAgeSeconds</literal>
- Lifespan of a node (in seconds) regardless of idle time before
the node is swept away. 0 denotes no limit. Nodes that
exceed this limit will be evicted whether or not a
<literal>maxNodes</literal> or <literal>timeToLiveSeconds</literal>
limit has been breached.
</listitem>
<listitem>
<literal>minTimeToLiveSeconds</literal>
- the minimum amount of time a node must be allowed to live after
being accessed before it is allowed to be considered for eviction.
0 denotes that this feature is disabled, which is the default value.
Should be set to a value less than <literal>timeToLiveSeconds</literal>.
It is recommended that this be set to a value slightly greater
than the maximum amount of time a transaction that affects the
region should take to complete. Configuring this is particularly
important when optimistic locking is used in conjunction with
invalidation.
</listitem>
</itemizedlist>
</sect3>
<sect3 id="eviction-overview-policies-null" revision="1">
<title>The <literal>NullEvictionPolicy</literal></title>
<para>
The <literal>org.jboss.cache.eviction.NullEvictionPolicy</literal>
is a simple policy that very efficiently does ... nothing. It
is used to efficiently short-circuit eviction handling for regions
where you don't want objects to be evicted (e.g. the timestamps
cache, which should <emphasis>never</emphasis> have data
evicted). Since the <literal>NullEvictionPolicy</literal> doesn't
actually evict anything, it doesn't take any configuration parameters.
</para>
</sect3>
</sect2>
</sect1>
<sect1 id="eviction-organization" revision="1">
<title>Organization of Data in the Cache</title>
<para>
In order to understand how to configure eviction, you need to
understand how Hibernate organizes data in the cache.
</para>
<sect2 id="eviction-organization-elements" revision="1">
<title>Region Prefix and Region Name</title>
<para>
All FQNs in a second level cache include two elements:
</para>
<itemizedlist>
<listitem>
<para>
A <emphasis>Region Prefix</emphasis>, which is simply
any value assigned to the
<literal>hibernate.cache.region_prefix</literal> Hibernate
configuration property. If no Region Prefix is set, this
portion of the FQN is omitted.
</para>
<para>
If different session factories are sharing the same underlying
JBoss Cache instance(s) it is <emphasis>strongly encouraged</emphasis>
that a distinct Region Prefix be assigned to each. This will
help ensure that the different session factories cache their
data in different subtrees in JBoss Cache.
</para>
</listitem>
<listitem>
<para>
A <emphasis>Region Name</emphasis>, which is either
<itemizedlist>
<listitem>
<para>
any value assigned to a <literal>&lt;cache&gt;</literal> element's
<literal>region</literal> attribute in a class or collection mapping.
See <xref linkend="eviction-organization-entity"/> for
an example.
</para>
</listitem>
<listitem>
<para>
Any value assigned to a Hibernate <literal>Query</literal>
object's <literal>cacheRegion</literal> property. See
<xref linkend="eviction-organization-query"/> for an
example.
</para>
</listitem>
<listitem>
<para>
The <emphasis>escaped class name</emphasis> of the type
being cached. An <emphasis>escaped class name</emphasis>
is simply a fully-qualified class name with any
<literal>.</literal> replaced with a <literal>/</literal>
-- for example <literal>org/example/Foo</literal>.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="eviction-organization-entity" revision="1">
<title>Entities</title>
<para>
The FQN for the cache region where entities of a particular class
are stored is derived as follows:
</para>
<para>
<literal>/</literal> + <emphasis>Region Prefix</emphasis> + <literal>/</literal>
+ <emphasis>Region Name</emphasis> + <literal>/ENTITY</literal>
</para>
<para>
If no region prefix was specified, the leading <literal>/</literal> and
<emphasis>Region Prefix</emphasis> is not included in the FQN.
So, if <literal>hibernate.cache.region_prefix</literal> was set to
"appA" and a class was mapped like this:
</para>
<programlisting><![CDATA[<class name="org.example.Foo">
<cache usage="transactional" region="foo_region"/>
....
</class>]]></programlisting>
<para>
The FQN of the region where <literal>Foo</literal> entities
would be cached is <literal>/appA/foo_region/ENTITY</literal>.
</para>
<para>
If the class mapping does not include a <literal>region</literal>
attribute, the region name is based on the name of the entity
class, e.g.
</para>
<programlisting><![CDATA[<class name="org.example.Bar">
<cache usage="transactional"/>
....
</class>]]></programlisting>
<para>
the FQN of the region where <literal>Bar</literal> entities
would be cached is <literal>/appA/org/example/Bar/ENTITY</literal>.
</para>
</sect2>
<sect2 id="eviction-organization-coll" revision="1">
<title>Collections</title>
<para>
The FQN for the cache region where entities of a particular class
is stored is derived as follows:
</para>
<para>
<literal>/</literal> + <emphasis>Region Prefix</emphasis> + <literal>/</literal>
+ <emphasis>Region Name</emphasis> + <literal>/COLL</literal>
</para>
<para>
So, let's say our example <literal>Foo</literal> entity
included a collection field <literal>bars</literal> that
we wanted to cache:
</para>
<programlisting><![CDATA[<class name="org.example.Foo">
<cache usage="transactional"/>
....
<set name="bars">
<cache usage="transactional" region="foo_region"/>
<key column="FOO_ID"/>
<one-to-many class="org.example.Bar"/>
</set>
</class>]]></programlisting>
<para>
The FQN of the region where the collection would be cached
would be
<literal>/appA/foo_region/COLL</literal>.
</para>
<para>
If the collection's <literal>&lt;cache&gt;</literal> element
did not include a <literal>region</literal>, the FQN would be
<literal>/appA/org/example/Foo/COLL</literal>.
</para>
</sect2>
<sect2 id="eviction-organization-query" revision="1">
<title>Queries</title>
<para>
Queries follow this pattern:
</para>
<para>
<literal>/</literal> + <emphasis>Region Prefix</emphasis> + <literal>/</literal>
+ <emphasis>Region Name</emphasis> + <literal>/QUERY</literal>
</para>
<para>
Say we had the following query (again with a region prefix set to
"appA"):
</para>
<programlisting><![CDATA[List blogs = sess.createQuery("from Blog blog " +
"where blog.blogger = :blogger")
.setEntity("blogger", blogger)
.setMaxResults(15)
.setCacheable(true)
.setCacheRegion("frontpages")
.list();]]></programlisting>
<para>
The FQN of the region where this query's results would be cached
would be <literal>/appA/frontpages/QUERY</literal>.
</para>
<para>
If the call to <literal>setCacheRegion("frontpages")</literal>
were ommitted, the <emphasis>Region Name</emphasis> portion of
the FQN would be based on a Hibernate class:
<literal>/appA/org/hibernate/cache/StandardQueryCache/QUERY</literal>
</para>
</sect2>
<sect2 id="eviction-organization-timestamps" revision="1">
<title>Timestamps</title>
<para>
Timestamps follow this pattern:
</para>
<para>
<literal>/TS/</literal> + <emphasis>Region Prefix</emphasis> +
<literal>/org/hibernate/cache/UpdateTimestampsCache</literal>
</para>
<para>
again with a <literal>/</literal> and the <emphasis>Region Prefix</emphasis>
portion omitted if no region prefix was set.
</para>
<para>
Note that in the timestamps case the special constant ("TS") comes
at the start of the FQN rather than the end. This makes it easier
to ensure that eviction is never enabled for the timestamps region.
</para>
</sect2>
</sect1>
<sect1 id="eviction-organization-example" revision="1">
<title>Example Configuration</title>
<para>
So far we've been looking at things in the abstract; let's see an
example of how this comes together. In this example, imagine we
have a Hibernate application with the following characteristics.
<itemizedlist>
<listitem>
<para>Query caching is enabled.</para>
</listitem>
<listitem>
<para>
There is a region prefix set as part of the Hibernate
configuration: <literal>hibernate.cache.region_prefix==appA</literal>
</para>
</listitem>
<listitem>
<para>
Some cachable entities and collections have a region
name of "reference" set in their Hibernate mapping.
</para>
</listitem>
<listitem>
<para>
Some cachable queries have the "reference" region name
set when they are created.
</para>
</listitem>
<listitem>
<para>
Other cachable entities and collections in the
<literal>org.example.hibernate</literal> package don't have a
region name set in their Hibernate mapping.
</para>
</listitem>
<listitem>
<para>
Other cachable queries don't have a region name set when they
are created.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Let's see a possible eviction configuration for this scenario:
</para>
<programlisting><![CDATA[<attribute name="EvictionPolicyConfig">
<config>
<attribute name="wakeUpIntervalSeconds">5</attribute>
<attribute name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
<!--
Default region to pick up anything we miss in the more
specific regions below.
-->
<region name="/_default_">
<attribute name="maxNodes">500</attribute>
<attribute name="timeToLiveSeconds">300</attribute>
<attribute name="minTimeToLiveSeconds">120</attribute>
</region>
<!-- Don't ever evict modification timestamps -->
<region name="/TS"
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
<!-- Reference data -->
<region name="/appA/reference">
<!-- Keep all reference data if it's being used -->
<attribute name="maxNodes">0</attribute>
<!-- Keep it around a long time (4 hours) -->
<attribute name="timeToLiveSeconds">14400</attribute>
<attribute name="minTimeToLiveSeconds">120</attribute>
</region>
<!-- Be more aggressive about queries on reference data -->
<region name="/appA/reference/QUERY">
<attribute name="maxNodes">200</attribute>
<attribute name="timeToLiveSeconds">1000</attribute>
<attribute name="minTimeToLiveSeconds">120</attribute>
</region>
<!--
Lots of entity instances from this package, but different
users are unlikely to share them. So, we can cache
a lot, but evict unused ones pretty quickly.
-->
<region name="/appA/org/example/hibernate">
<attribute name="maxNodes">50000</attribute>
<attribute name="timeToLiveSeconds">1200</attribute>
<attribute name="minTimeToLiveSeconds">120</attribute>
</region>
<!-- Clean up misc queries very promptly -->
<region name="/appA/org/hibernate/cache/StandardQueryCache">
<attribute name="maxNodes">200</attribute>
<attribute name="timeToLiveSeconds">240</attribute>
<attribute name="minTimeToLiveSeconds">120</attribute>
</region>
</config>
</attribute>]]></programlisting>
<para>
Notes on the above:
<itemizedlist>
<listitem>
<para>The <literal>wakeUpIntervalSeconds</literal> configuration
controls how often the background eviction process kicks
in to evict nodes.
</para>
</listitem>
<listitem>
<para>The first <literal>policyClass</literal> configuration
sets the default eviction policy class to use for each region.
Here we want to use the standard <literal>LRUPolicy</literal>
This can be overridden on a per-region basis, as is done
here for the <literal>/TS</literal> region.</para>
</listitem>
<listitem>
<para>We set up a <literal>/_default_</literal> region. Having
such a region is a requirement if eviction is used. Here we
don't expect any data to end up in this default region, but
if by mistake someone adds a new entity type that doesn't fall
into one of our other regions, we may not have a large memory
budget for it so we evict fairly agressively.
</para>
</listitem>
<listitem>
<para>Evicting timestamps is forbidden, so we add a
<literal>/TS</literal> region that disables it. Here we
see how to override the default eviction policy.</para>
</listitem>
<listitem>
<para>
The <literal>/appA/reference</literal> region covers our
reference data entities and collections. This is our most
likely to be reused data, so we configure the cache to be
very slow to evict it.
</para>
</listitem>
<listitem>
<para>
The queries related to our reference data are less likely to
be reused, and may take up a lot of memory, so we override the
<literal>/appA/reference</literal> region with a
<literal>/appA/reference/QUERY</literal> region that is more
agressive about eviction.
</para>
</listitem>
<listitem>
<para>
The <literal>org.example.hibernate</literal> package includes a
lot of entity classes like <literal>Order</literal>, where
there are hundreds of thousands of records in the database.
These are unlikely to be reused across users, but we have a lot
of users and want to be able to cache many of them so a user
can have fast access to his or her data during the
course of their interaction with the system. So we create a
<literal>/appA/org/example/hibernate</literal> region
with a high <literal>maxNodes</literal> value but a fairly
low <literal>timeToLiveSeconds</literal>. The low time-to-live
ensures an <literal>Order</literal> is evicted quickly once a
user is done with it.
</para>
</listitem>
<listitem>
<para>Finally, cacheable queries that aren't assigned to
to the <literal>reference</literal> region will end up in
<literal>/appA/org/hibernate/cache/StandardQueryCache</literal>.
We've elected not to keep these around long at all.
</para>
</listitem>
</itemizedlist>
</para>
</sect1>
<sect1 id="eviction-organization-best" revision="1">
<title>Best Practices</title>
<para>
Some best practices to follow:
</para>
<itemizedlist>
<listitem>
<para>
Set <literal>hibernate.cache.region_prefix</literal> in your
configuration. It makes it simple to ensure the different session
factories don't step on each other if they share a JBoss Cache
instance.
</para>
</listitem>
<listitem>
<para>
Always set up an eviction region for the <literal>/TS</literal>
FQN that uses the <literal>NullEvictionPolicy</literal>. This
will ensure that timestamps never get evicted. Even if you are
not doing query caching or aren't caching timestamps in a
particular cache, this is still a good practice, as it costs
almost nothing and helps to ensure that timestamp eviction doesn't
slip in unnoticed later.
</para>
</listitem>
<listitem>
<para>
Assign a region to your entities, collections and queries rather
than relying on class names to compose the FQN. It makes
it easier to set up eviction, and helps prevent your eviction
setup breaking if class names are refactored.
</para>
</listitem>
<listitem>
<para>
Assign a different region name to your entities, collections or
queries that have different desirable eviction characteristics.
Put objects like often used reference data in one region, data
probably only accessed by a single user in another. Aggressively
evict the latter region; be less agressive with the former if
you evict it at all.
</para>
</listitem>
<listitem>
<para>
In some cases, there is an external application (i.e. outside
of Hibernate's control) that can modify data in the database.
Generally, a Second Level Cache should not be used in this sort
of case, since it can result in data in the cache being out of
date with respect to the database. But sometimes application
designers can tolerate having out of date data in the cache. In
this sort of situation, use an <literal>LRUPolicy</literal> with
a fairly low <literal>maxAgeSeconds</literal>. This will ensure
that out-of-date data eventually gets flushed from the cache.
</para>
</listitem>
</itemizedlist>
</sect1>
</chapter>

View File

@ -1,221 +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">
<!--
~ Copyright (c) 2009, Red Hat, Inc. All rights reserved.
~
~ 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, v. 2.1. This program is distributed in the
~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
~ distribution; if not, write to the Free Software Foundation, Inc.,
~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
~
~ Red Hat Author(s): Brian Stansberry
-->
<chapter id="introduction">
<title>Introduction</title>
<sect1 id="introduction-overview" revision="1">
<title>Overview</title>
<para>
JBoss Cache is a tree-structured, clustered, transactional cache. It
includes support for maintaining cache consistency across multiple
cache instances running in a cluster. It integrates with JTA transaction
managers, supporting transaction-scoped locking of cache elements and
automatic rollback of cache changes upon transaction rollback. It
supports both pessimistic and optimistic locking, with the tree-structure
of the cache allowing maximum concurrency.
</para>
<para>
All of these features make JBoss Cache an excellent choice for use as a
Hibernate <emphasis>Second Level Cache</emphasis>, particularly in
a clustered environment. A Hibernate <literal>Session</literal> is a
transaction-scoped cache of persistent data -- data accessed via the
<literal>Session</literal> is cached in the <literal>Session</literal>
for the duration of the current transaction, and then is cleared. A
<emphasis>Second Level Cache</emphasis> is an optional cluster or
JVM-level cache whose contents are maintained beyond the life of a
transaction and whose contents can be shared across transactions.
Use of a Second Level Cache is configured as part of the configuration
of the Hibernate <literal>SessionFactory</literal>. If a Second Level
Cache is enabled, caching of an instance of a particular
entity class or of results of a particular query can be configured on
a class-by-class, collection-by-collection and query-by-query basis.
See the <emphasis>Hibernate Reference Documentation</emphasis> for more
on Second Level Cache basics and how to configure entity classes,
collections and queries for caching.
</para>
<para>
The JBoss Cache Second Level Cache integration supports the
<literal>transactional</literal> and <literal>read only</literal>
<emphasis>cache concurrency strategies</emphasis> discussed in the
<emphasis>Hibernate Reference Documentation</emphasis>. It supports
query caching and is, of course, cluster safe.
</para>
</sect1>
<sect1 id="introduction-requirements" revision="1">
<title>Requirements</title>
<sect2 id="introduction-requirements-dependencies" revision="1">
<title>Dependencies</title>
<para>
Second level caching with JBoss Cache 3 requires the use of JBoss
Cache 3.1.0 or later. The core JBoss Cache project is used; the
related POJO Cache project/library is not needed. The following jars,
included with the JBoss Cache distribution, need to be on the classpath:
</para>
<itemizedlist>
<listitem><para>jbosscache-core.jar</para></listitem>
<listitem><para>commons-logging.jar</para></listitem>
<listitem><para>jboss-common-core.jar</para></listitem>
<listitem><para>jgroups.jar</para></listitem>
</itemizedlist>
<para>
JBoss Cache also needs to have the classes in the
<literal>javax.transaction</literal> package on the classpath,
but those are already included in the Hibernate distribution.
</para>
<para>
The <literal>hibernate-jbosscache.jar</literal> that is included with
the Hibernate distribution also needs to be on the classpath.
</para>
<para>
A JBoss Cache configuration file, and usually a JGroups configuration
file<footnote><para><ulink url="http://labs.jboss.org/jgroups">JGroups</ulink>
is the group communication library used by JBoss Cache for intra-cluster
communication.</para></footnote>, need to be on the classpath. The
<literal>hibernate-jbosscache.jar</literal> includes standard
configuration files in the <literal>org.hibernate.cache.jbc.builder</literal>
package. The <literal>jbc-configs.xml</literal> file is for JBoss
Cache and the <literal>jgroups-stacks.xml</literal> file is for JGroups.
See <xref linkend="jbc-config"/> and <xref linkend="jgroups-config"/>
for more details on these files. Users can create their own versions
and tell the <literal>SessionFactory</literal> to use them; see
<xref linkend="sessionfactory"/> for details.
</para>
</sect2>
<sect2 id="introduction-requirements-transactions" revision="1">
<title>JTA Transactional Support</title>
<para>
JBoss Cache requires integration with a JTA
<literal>TransactionManager</literal> in order to meet the requirements
of the second level caching use case. This means your Hibernate
application must be configured to use JTA:
</para>
<itemizedlist>
<listitem>
<para>
You must configure a <literal>hibernate.transaction.manager_lookup_class</literal>.
</para>
</listitem>
<listitem>
<para>
You must configure a <literal>hibernate.transaction.factory_class</literal>,
specifying a transaction factory that supports JTA. In practice, this means
<literal>org.hibernate.transaction.JTATransactionFactory</literal> if
you are using JTA directly, or <literal>org.hibernate.transaction.CMTTransactionFactory</literal>
if you are accessing Hibernate via a CMT session bean.
</para>
</listitem>
<listitem>
<para>
Finally, make sure <literal>hibernate.current_session_context_class</literal>
is either unset (backwards compatiblity), or set to <literal>"jta"</literal>.
</para>
</listitem>
</itemizedlist>
<para>
See the <emphasis>Hibernate Reference Documentation</emphasis> for
an in-depth discussion of using Hibernate with JTA
</para>
</sect2>
</sect1>
<sect1 id="introduction-configuration" revision="1">
<title>Configuration Basics</title>
<para>
The key steps in using JBoss Cache as a second level cache are to:
</para>
<itemizedlist>
<listitem>
<para>
Tell Hibernate in your <literal>SessionFactory</literal>
configuration that you want to use JBoss Cache as your
Second Level Cache implementation:
</para>
<programlisting><![CDATA[hibernate.cache.region.factory_class=
org.hibernate.cache.jbc.MultiplexedJBossCacheRegionFactory]]></programlisting>
<para>
There are a number of values that can be provided for the
<literal>hibernate.cache.region.factory_class</literal>
property, depending on how you want the JBoss Cache integration
to work. Based on what factory class you specify, there are
additional detail configuration properties you can add to further
control that factory. However, simply specifying the
<literal>MultiplexedJBossCacheRegionFactory</literal> shown
above provides a reasonable set of default values useful for
many applications. See <xref linkend="sessionfactory-factories"/>
for more details.
</para>
<para>
Do not set the legacy <literal>hibernate.cache.provider_class</literal>
property when using JBoss Cache 3. That is a legacy property
from before Hibernate 3.3's redesign of second level caching
internals. It will not work with JBoss Cache 3.
</para>
</listitem>
<listitem>
<para>
Tell Hibernate you want to enable caching of entities and
collections. No need to set this property if you don't:
</para>
<programlisting><![CDATA[hibernate.cache.use_second_level_cache=true]]></programlisting>
</listitem>
<listitem>
<para>
Tell Hibernate you want to enable caching of
query results. No need to set this property if you don't:
</para>
<programlisting><![CDATA[hibernate.cache.use_query_cache=true]]></programlisting>
</listitem>
<listitem>
<para>
If you have enabled caching of query results, tell Hibernate if
you want to suppress costly replication of those results around
the cluster. No need to set this property if you want query
results replicated:
</para>
<programlisting><![CDATA[hibernate.cache.jbc.query.localonly=true]]></programlisting>
</listitem>
</itemizedlist>
<para>
See <xref linkend="configuration"/> for full details on configuration.
</para>
</sect1>
</chapter>

View File

@ -1,166 +0,0 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!--
~ Copyright (c) 2009, Red Hat, Inc. All rights reserved.
~
~ 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, v. 2.1. This program is distributed in the
~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
~ distribution; if not, write to the Free Software Foundation, Inc.,
~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
~
~ Red Hat Author(s): Brian Stansberry
-->
<preface id="preface" revision="1">
<title>Preface</title>
<para>
This document is focused on the use of the
<ulink url="http://labs.jboss.org/jbosscache">JBoss Cache</ulink>
clustered transactional caching library as a tool for caching data in
a Hibernate-based application.
</para>
<para>
Working with object-oriented software and a relational database can be cumbersome
and time consuming in today's enterprise environments. Hibernate is an object/relational
mapping tool for Java environments. The term object/relational mapping (ORM) refers to
the technique of mapping a data representation from an object model to a relational
data model with a SQL-based schema.
</para>
<para>
Hibernate not only takes care of the mapping from Java classes to
database tables (and from Java data types to SQL data types), but also provides data
query and retrieval facilities and can significantly reduce development time otherwise
spent with manual data handling in SQL and JDBC.
</para>
<para>
In any application that works with a relational database, caching data
retrieved from the database can potentially improve application performance.
Hibernate provides a number of facilities for caching data on the
database client side, i.e. in the Java process in which Hibernate is
running. The primary facility is the Hibernate <literal>Session</literal>
itself, which maintains a transaction-scoped cache of persistent data.
If you wish to cache data beyond the scope of a transaction, it is
possible to configure a cluster or JVM-level (technically a
<literal>SessionFactory</literal>-level) cache on a class-by-class,
collection-by-collection and query-by-query basis. This type of cache
is referred to as a <emphasis>Second Level Cache</emphasis>.
</para>
<para>
Hibernate provides a pluggable architecture for implementing its
Second Level Cache, allowing it to integrate with a number of third-party
caching libraries. This document is focused on the use of the
<ulink url="http://labs.jboss.org/jbosscache">JBoss Cache</ulink>
clustered transactional caching library as an implementation of
the Second Level Cache. It specifically focuses on JBoss Cache 3.
</para>
<para>
If you are new to Hibernate and Object/Relational Mapping or even Java,
please follow these steps:
</para>
<orderedlist>
<listitem>
<para>
Read the <emphasis>Hibernate Reference Documentation</emphasis>,
particularly the <emphasis>Introduction</emphasis> and
<emphasis>Architecture</emphasis> sections.
</para>
</listitem>
<listitem>
<para>
Have a look at the <literal>eg/</literal> directory in the Hibernate
distribution, it contains a simple standalone application. Copy your
JDBC driver to the <literal>lib/</literal> directory and edit
<literal>etc/hibernate.properties</literal>, specifying correct values for
your database. From a command prompt in the distribution directory,
type <literal>ant eg</literal> (using Ant), or under Windows, type
<literal>build eg</literal>.
</para>
</listitem>
<listitem>
<para>
Use the <emphasis>Hibernate Reference Documentation</emphasis>
as your primary source of information.
Consider reading <emphasis>Java Persistence with Hibernate</emphasis>
(http://www.manning.com/bauer2) if you need more help with application
design or if you prefer a step-by-step tutorial. Also visit
http://caveatemptor.hibernate.org and download the example application
for Java Persistence with Hibernate.
</para>
</listitem>
<listitem>
<para>
FAQs are answered on the Hibernate website.
</para>
</listitem>
<listitem>
<para>
Third party demos, examples, and tutorials are linked on the Hibernate
website.
</para>
</listitem>
<listitem>
<para>
The Community Area on the Hibernate website is a good resource for
design patterns and various integration solutions (Tomcat, JBoss AS,
Struts, EJB, etc.).
</para>
</listitem>
</orderedlist>
<para>
If you are new to the Hibernate Second Level Cache or to JBoss Cache,
please follow these steps:
</para>
<orderedlist>
<listitem>
<para>
Read the <emphasis>Hibernate Reference Documentation</emphasis>,
particularly the <emphasis>Second Level Cache</emphasis> and
<emphasis>Configuration</emphasis> sections.
</para>
</listitem>
<listitem>
<para>
Read the
<ulink url="http://labs.jboss.org/jbosscache/docs/index.html">JBoss Cache User Guide, Core Edition</ulink>.
</para>
</listitem>
<listitem>
<para>
Use this guide as your primary source of information on the
usage of JBoss Cache 3 as a Hibernate Second Level Cache.
</para>
</listitem>
</orderedlist>
<para>
If you have questions, use the user forum linked on the Hibernate website.
The user forum on the JBoss Cache website is also useful.
We also provide a JIRA issue tracking system for bug reports and feature requests. If you
are interested in the development of Hibernate, join the developer mailing list. If
you are interested in translating this documentation into your language, contact us
on the developer mailing list.
</para>
<para>
Commercial development support, production support, and training for Hibernate is
available through Red Hat, Inc. (see http://www.hibernate.org/SupportTraining/).
Hibernate is a Professional Open Source project and a critical component of the
JBoss Enterprise Application Platform.
</para>
</preface>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1,52 +0,0 @@
<?xml version='1.0' encoding="UTF-8"?>
<!--
~ Copyright (c) 2008, Red Hat Middleware, LLC. All rights reserved.
~
~ 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, v. 2.1. This program is distributed in the
~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
~ distribution; if not, write to the Free Software Foundation, Inc.,
~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
~
~ Red Hat Author(s): Brian Stansberry
-->
<!DOCTYPE legalnotice PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<legalnotice id="Legal_Notice">
<title>Legal Notice</title>
<para>
<address>
<street>1801 Varsity Drive</street>
<city>Raleigh</city>, <state>NC</state><postcode>27606-2072</postcode><country>USA</country>
<phone>Phone: +1 919 754 3700</phone>
<phone>Phone: 888 733 4281</phone>
<fax>Fax: +1 919 754 3701</fax>
<pob>PO Box 13588</pob><city>Research Triangle Park</city>, <state>NC</state><postcode>27709</postcode><country>USA</country>
</address>
</para>
<para>
Copyright <trademark class="copyright"/> 2008 by Red Hat, Inc. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, V1.0 or later (the latest version is presently available at <ulink url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).
</para>
<para>
Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder.
</para>
<para>
Distribution of the work or derivative of the work in any standard (paper) book form for commercial purposes is prohibited unless prior permission is obtained from the copyright holder.
</para>
<para>
Red Hat and the Red Hat "Shadow Man" logo are registered trademarks of Red Hat, Inc. in the United States and other countries.
</para>
<para>
All other trademarks referenced herein are the property of their respective owners.
</para>
<para>
The GPG fingerprint of the security@redhat.com key is:
</para>
<para>
CA 20 86 86 2B D6 9D FC 65 F6 EC C4 21 91 80 CD DB 42 A6 0E
</para>
</legalnotice>

View File

@ -13,49 +13,37 @@
and
<literal>TGZ</literal>
formats. Each release bundle contains<literal>JARs</literal>,
documentation, source code, and other information.
documentation, source code, and other goodness.
</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/"/>.
<ulink url="http://sourceforge.net/projects/hibernate/files/hibernate4/"/>.
</para>
<itemizedlist>
<listitem>
<para>
<filename>hibernate3.jar</filename>
is an aggregation of all the Hibernate Core classes.
This must be included in your project's classpath.
The <filename>lib/required/</filename> directory contains all the JARs Hibernate requires. All the
jars in this directory must also 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/jpa/</filename> directory contains the
<systemitem>hibernate-entitymanager</systemitem> jar and its dependencies beyond those
in <filename>lib/required/</filename>. This defines Hibernate support for
<ulink url="http://jcp.org/en/jsr/detail?id=317">JPA</ulink>.
</para>
<important>
<para>
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.
</para>
</important>
</listitem>
<listitem>
<para>
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.
The <filename>lib/envers</filename> directory contains the <systemitem>hibernate-envers</systemitem>
jar and its dependencies beyond those in <filename>lib/required/</filename>
</para>
</listitem>
<listitem>
<para>
The <filename>lib/optional</filename> directory contains the jars needed for optional features of
Hibernate.
</para>
</listitem>
</itemizedlist>
@ -65,38 +53,33 @@
<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.
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>
<itemizedlist>
<title>Maven Repository Wiki Pages</title>
<listitem>
<para>
<ulink url="http://community.jboss.org/docs/DOC-14900"/> -
General information about the repository.
<ulink url="http://community.jboss.org/docs/DOC-14900"/> - General information about the repository.
</para>
</listitem>
<listitem>
<para>
<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.
<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>
<listitem>
<para>
<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.
<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>
</itemizedlist>
</note>
<para>
Hibernate produces a number of artifacts (all under the org.hibernate groupId):
Hibernate produces a number of artifacts (all under the <systemitem>org.hibernate</systemitem> groupId):
</para>
<variablelist>
<title>Hibernate Artifacts under groupId <systemitem>org.hibernate</systemitem>
@ -105,12 +88,9 @@
<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
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.
The main artifact, needed to build applications using the native Hibernate APIs including
defining metadata in both annotations as well as Hibernate's own <filename>hbm.xml</filename>
format.
</para>
</listitem>
</varlistentry>
@ -130,8 +110,7 @@
<term>hibernate-envers</term>
<listitem>
<para>
An optional module that provides historical auditing of changes
to your entities.
An optional module that provides historical auditing of changes to your entities.
</para>
<para>
This artifact depends on both <systemitem>hibernate-core</systemitem>
@ -199,51 +178,6 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<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>.
</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>
dependencies automatically.
</para>
</listitem>
</varlistentry>
<varlistentry>
<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>.
</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>OSCache</application>
dependencies automatically.
</para>
</listitem>
</varlistentry>
<varlistentry>
<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>.
</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.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</chapter>

View File

@ -25,9 +25,7 @@
<title><filename>persistence.xml</filename></title>
<para>
This file was discussed in the <systemitem>JPA</systemitem> tutorial in <xref
linkend="hibernate-gsg-tutorial-jpa-config" />, and is largely the same here. The major difference is the set
of properties defining <firstterm>listeners</firstterm>. Listeners enable Envers to receive notfications from
Hibernate processing about <firstterm>events</firstterm> such as saving or updating of entities.
linkend="hibernate-gsg-tutorial-jpa-config" />, and is essentially the same here.
</para>
</section>
@ -44,7 +42,7 @@
<title>Example code</title>
<para>
Again, this tutorial makes use of the <systemitem>JPA</systemitem> APIs. However, the code also makes a change to one
of the entites, then uses the Envers API to pull back the initial <firstterm>revision</firstterm> as well as the updated
of the entities, then uses the Envers API to pull back the initial <firstterm>revision</firstterm> as well as the updated
revision. A revision refers to a version of an entity.
</para>
<example id="hibernate-gsg-tutorial-envers-test-api">
@ -82,15 +80,15 @@
<itemizedlist>
<title>Practice Exercises</title>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
</para>
<para>
Provide a custom revision entity to additionally capture who made the changes.
</para>
</listitem>
<listitem>
<para>
todo : adam, another?
</para>
</listitem>
</itemizedlist>
</section>

View File

@ -29,7 +29,7 @@
<parent>
<groupId>org.hibernate.tutorials</groupId>
<artifactId>hibernate-tutorials</artifactId>
<version>3.6.0-SNAPSHOT</version>
<version>@VERSION@</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -29,7 +29,7 @@
<parent>
<groupId>org.hibernate.tutorials</groupId>
<artifactId>hibernate-tutorials</artifactId>
<version>3.6.0-SNAPSHOT</version>
<version>@VERSION@</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -27,9 +27,9 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>hibernate-tutorials</artifactId>
<groupId>org.hibernate.tutorials</groupId>
<version>3.6.0-SNAPSHOT</version>
<artifactId>hibernate-tutorials</artifactId>
<version>@VERSION@</version>
</parent>
<artifactId>hibernate-tutorial-entitymanager</artifactId>
@ -45,7 +45,7 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${project.version}</version>
<version>@VERSION@</version>
</dependency>
</dependencies>

View File

@ -27,9 +27,9 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>hibernate-tutorials</artifactId>
<groupId>org.hibernate.tutorials</groupId>
<version>3.6.0-SNAPSHOT</version>
<artifactId>hibernate-tutorials</artifactId>
<version>@VERSION@</version>
</parent>
<artifactId>hibernate-tutorial-envers</artifactId>
@ -44,13 +44,13 @@
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${project.version}</version>
<artifactId>hibernate-envers</artifactId>
<version>@VERSION@</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<version>${project.version}</version>
<artifactId>hibernate-entitymanager</artifactId>
<version>@VERSION@</version>
</dependency>
</dependencies>

View File

@ -28,7 +28,7 @@
<groupId>org.hibernate.tutorials</groupId>
<artifactId>hibernate-tutorials</artifactId>
<version>3.6.0-SNAPSHOT</version>
<version>@VERSION@</version>
<packaging>pom</packaging>
<name>Hibernate Getting Started Guide Tutorials</name>
@ -50,23 +50,16 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${project.version}</version>
<version>@VERSION@</version>
</dependency>
<!-- Hibernate uses slf4j for logging, for our purposes here use the simple backend -->
<!-- Hibernate uses jboss-logging for logging, for the tutorials we will use the sl4fj-simple backend -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
</dependency>
<!-- Hibernate gives you a choice of bytecode providers between cglib and javassist -->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.0.GA</version>
</dependency>
<!-- The tutorials use JUnit test cases to illustrate usage -->
<dependency>
<groupId>junit</groupId>

View File

@ -10,8 +10,8 @@ dependencies {
}
compile( libraries.commons_annotations )
compile( libraries.jpa )
compile( libraries.javassist )
antlr( libraries.antlr )
provided( libraries.javassist )
provided( libraries.ant )
provided( libraries.jacc )
provided( libraries.validation )
@ -42,55 +42,4 @@ ideaModule {
sourceDirs.add( file( '$buildDir/generated-src/antlr/main' ) )
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// This entire section below is all about creating, installing and uploading the hibernate-testing artifacts.
// This is obviously extremely verbose. Check back once Gradle goes m2 for 1.0 to see about the MavenPublication
// approach Adam talked about as a means to make this more succinct and natural.
// todo : check back once Gradle goes m2 for 1.0 to see about the MavenPublication approach
configurations {
testing
}
task testingJar(type: Jar, dependsOn: compileTestJava) {
from sourceSets.test.classes
includes += "org/hibernate/testing/**"
baseName = 'hibernate-testing'
}
task testingSourcesJar(type: Jar, dependsOn: compileTestJava) {
from sourceSets.test.allSource
includes += "org/hibernate/testing/**"
baseName = 'hibernate-testing'
classifier = 'sources'
}
artifacts {
testing testingJar, testingSourcesJar
}
// ugh, lots of duplication with uploadArchives
uploadTesting {
repositories.mavenDeployer {
name = 'jbossDeployer'
configuration = configurations.deployerJars
pom.project basePomConfig
pom.artifactId = 'hibernate-testing'
repository(id: "jboss-releases-repository", url: "https://repository.jboss.org/nexus/service/local/staging/deploy/maven2/")
snapshotRepository(id: "jboss-snapshots-repository", url: "https://repository.jboss.org/nexus/content/repositories/snapshots")
}
}
uploadArchives.dependsOn uploadTesting
task installTesting(type:Upload, dependsOn: [testingJar,testingSourcesJar]) {
configuration = configurations.testing
repositories.mavenInstaller {
name = RepositoryHandler.DEFAULT_MAVEN_INSTALLER_NAME
pom.project basePomConfig
pom.artifactId = 'hibernate-testing'
}
}
install.dependsOn installTesting
uploadTesting.dependsOn installTesting

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* Copyright (c) 2008-2011, 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 Middleware LLC.
* 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
@ -22,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.envers;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -29,14 +30,15 @@ import java.lang.annotation.Target;
/**
* Marks an entity to be created whenever a new revision is generated. The revisions entity must have
* an integer-valued unique property (preferrably the primary id) annotated with {@link RevisionNumber}
* an integer-valued unique property (preferably the primary id) annotated with {@link RevisionNumber}
* and a long-valued property annotated with {@link RevisionTimestamp}. The {@link DefaultRevisionEntity}
* already has those two fields, so you may extend it, but you may also write your own revision entity
* from scratch.
*
* @author Adam Warski (adam at warski dot org)
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RevisionEntity {
Class<? extends RevisionListener> value() default RevisionListener.class;
Class<? extends RevisionListener> value() default RevisionListener.class;
}

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* Copyright (c) 2008-2011, 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 Middleware LLC.
* 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
@ -22,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.envers;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -32,6 +33,7 @@ import java.lang.annotation.Target;
* {@link RevisionListener}. Values of this property should form a strictly-increasing sequence
* of numbers. The value of this property won't be set by Envers. In most cases, this should be
* an auto-generated database-assigned primary id.
*
* @author Adam Warski (adam at warski dot org)
* @author Sanne Grinovero
*/

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* Copyright (c) 2008-2011, 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 Middleware LLC.
* 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
@ -22,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.envers;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -30,6 +31,7 @@ import java.lang.annotation.Target;
/**
* Marks a property which will hold the timestamp of the revision in a revision entity, see
* {@link RevisionListener}. The value of this property will be automatically set by Envers.
*
* @author Adam Warski (adam at warski dot org)
* @author Sanne Grinovero
*/

View File

@ -117,16 +117,14 @@ releaseCopySpec = copySpec {
from parent.project( 'hibernate-core' ).configurations.provided.files { dep -> dep.name == 'jta' }
from parent.project( 'hibernate-core' ).configurations.runtime
from parent.project( 'hibernate-core' ).configurations.archives.allArtifactFiles.filter{ file -> !file.name.endsWith('-sources.jar') }
}
into('lib/bytecode/cglib') {
from parent.project( 'hibernate-core' ).configurations.provided.files { dep -> dep.name == 'cglib' }
}
into('lib/bytecode/javassist') {
// for now,
from parent.project( 'hibernate-core' ).configurations.provided.files { dep -> dep.name == 'javassist' }
}
// into('lib/bytecode/javassist') {
// from parent.project( 'hibernate-core' ).configurations.provided.files { dep -> dep.name == 'javassist' }
// }
into( 'lib/jpa' ) {
from parent.project( 'hibernate-entitymanager' ).configurations.archives.allArtifactFiles.filter{ file -> !file.name.endsWith('-sources.jar') }
}
@ -158,11 +156,9 @@ releaseCopySpec = copySpec {
}
}
into('documentation') {
from new File( parent.project( 'documentation' ).buildDir, 'docbook/publish' )
}
into('documentation') {
from new File( parent.project( 'documentation' ).buildDir, 'docbook/publish' )
}
into('documentation/javadocs') {
from javadocBuildDir.dir