Adding the missing chapter on queries

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@15590 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Adam Warski 2008-11-19 13:49:52 +00:00
parent ef45d04181
commit a499ae2273
4 changed files with 209 additions and 4 deletions

View File

@ -51,6 +51,7 @@
<xi:include href="content/example.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/revisionlog.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/queries.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/schema.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/tables.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="content/source.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

View File

@ -49,6 +49,11 @@
and so on.
</para>
<para>
Also, the query interface has changed slightly, mainly in the part for specifying restrictions,
projections and order. Please refer to the API for further details.
</para>
</sect1>
<sect1 id="migrations-configuration">

View File

@ -0,0 +1,203 @@
<?xml version='1.0' encoding="UTF-8"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
~ indicated by the @author tags or express copyright attribution
~ statements applied by the authors. All third-party contributions are
~ distributed under license by Red Hat Middleware LLC.
~
~ This copyrighted material is made available to anyone wishing to use, modify,
~ copy, or redistribute it subject to the terms and conditions of the GNU
~ Lesser General Public License, as published by the Free Software Foundation.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
~ for more details.
~
~ You should have received a copy of the GNU Lesser General Public License
~ along with this distribution; if not, write to:
~ Free Software Foundation, Inc.
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="queries">
<title>Queries</title>
<para>
You can think of historic data as having two dimension. The first - horizontal -
is the state of the database at a given revision. Thus, you can
query for entities as they were at revision N. The second - vertical - are the
revisions, at which entities changed. Hence, you can query for revisions,
in which a given entity changed.
</para>
<para>
The queries in Envers are similar to
<ulink url="http://www.hibernate.org/hib_docs/v3/reference/en/html/querycriteria.html">Hibernate Criteria</ulink>,
so if you are common with them, using Envers queries will be much easier.
</para>
<para>
The main limitation of the current queries implementation is that you cannot
traverse relations. You can only specify constraints on the ids of the
related entities, and only on the "owning" side of the relation. This however
will be changed in future releases.
</para>
<para>
Please note, that queries on the audited data will be in many cases much slower
than corresponding queries on "live" data, as they involve correlated subselects.
</para>
<sect1 id="entities-at-revision">
<title>Querying for entities of a class at a given revision</title>
<para>
The entry point for this type of queries is:
</para>
<programlisting><![CDATA[AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(MyEntity.class, revisionNumber);]]></programlisting>
<para>
You can then specify constraints, which should be met by the entities returned, by
adding restrictions, which can be obtained using the <literal>AuditEntity</literal>
factory class. For example, to select only entities, where the "name" property
is equal to "John":
</para>
<programlisting><![CDATA[query.add(AuditEntity.property("name").eq("John"));]]></programlisting>
<para>
And to select only entites that are related to a given entity:
</para>
<programlisting><![CDATA[query.add(AuditEntity.property("address").eq(relatedEntityInstance));
// or
query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]></programlisting>
<para>
You can limit the number of results, order them, and set aggregations and projections
(except grouping) in the usual way.
When your query is complete, you can obtain the results by calling the
<literal>getSingleResult()</literal> or <literal>getResultList()</literal> methods.
</para>
<para>
A full query, can look for example like this:
</para>
<programlisting><![CDATA[List personsAtAddress = getAuditReader().createQuery()
.forEntitiesAtRevision(Person.class, 12)
.addOrder(AuditEntity.property("surname").desc())
.add(AuditEntity.relatedId("address").eq(addressId))
.setFirstResult(4)
.setMaxResults(2)
.getResultList();]]></programlisting>
</sect1>
<sect1 id="revisions-of-entity">
<title>Querying for revisions, at which entities of a given class changed</title>
<para>
The entry point for this type of queries is:
</para>
<programlisting><![CDATA[AuditQuery query = getAuditReader().createQuery()
.forRevisionsOfEntity(MyEntity.class, false, true);]]></programlisting>
<para>
You can add constraints to this query in the same way as to the previous one.
There are some additional possibilities:
</para>
<orderedlist>
<listitem>
using <literal>AuditEntity.revisionNumber()</literal> you can specify constraints, projections
and order on the revision number, in which the audited entity was modified
</listitem>
<listitem>
similarly, using <literal>AuditEntity.revisionProperty(propertyName)</literal> you can specify constraints,
projections and order on a property of the revision entity, corresponding to the revision
in which the audited entity was modified
</listitem>
<listitem>
<literal>AuditEntity.revisionType()</literal> gives you access as above to the type of
the revision (ADD, MOD, DEL).
</listitem>
</orderedlist>
<para>
Using these methods,
you can order the query results by revision number, set projection or constraint
the revision number to be greater or less than a specified value, etc. For example, the
following query will select the smallest revision number, at which entity of class
<literal>MyEntity</literal> with id <literal>entityId</literal> has changed, after revision
number 42:
</para>
<programlisting><![CDATA[Number revision = (Number) getAuditReader().createQuery()
.forRevisionsOfEntity(MyEntity.class, false, true)
.setProjection(AuditEntity.revisionNumber().min())
.add(AuditEntity.id().eq(entityId))
.add(AuditEntity.revisionNumber().gt(42))
.getSingleResult();]]></programlisting>
<para>
The second additional feature you can use in queries for revisions is the ability
to maximalize/minimize a property. For example, if you want to select the
revision, at which the value of the <literal>actualDate</literal> for a given entity
was larger then a given value, but as small as possible:
</para>
<programlisting><![CDATA[Number revision = (Number) getAuditReader().createQuery()
.forRevisionsOfEntity(MyEntity.class, false, true)
// We are only interested in the first revision
.setProjection(AuditEntity.revisionNumber().min())
.add(AuditEntity.property("actualDate").minimize()
.add(AuditEntity.property("actualDate").ge(givenDate))
.add(AuditEntity.id().eq(givenEntityId)))
.getSingleResult();
]]></programlisting>
<para>
The <literal>minimize()</literal> and <literal>maximize()</literal> methods return a criteria,
to which you can add constraints, which must be met by the entities with the
maximized/minimized properties.
</para>
<para>
You probably also noticed that there are two boolean parameters, passed when
creating the query. The first one, <literal>selectEntitiesOnly</literal>, is only valid when
you don't set an explicit projection. If true, the result of the query will be
a list of entities (which changed at revisions satisfying the specified
constraints).
</para>
<para>
If false, the result will be a list of three element arrays. The
first element will be the changed entity instance. The second will be an entity
containing revision data (if no custom entity is used, this will be an instance
of <literal>DefaultRevisionEntity</literal>). The third will be the type of the
revision (one of the values of the <literal>RevisionType</literal> enumeration:
ADD, MOD, DEL).
</para>
<para>
The second parameter, <literal>selectDeletedEntities</literal>, specifies if revisions,
in which the entity was deleted should be included in the results. If yes, such entities
will have the revision type DEL and all fields, except the id,
<literal>null</literal>.
</para>
</sect1>
</chapter>

View File

@ -68,9 +68,5 @@
data is correct (the testHistoryOfXxx methods).
</para>
<para>
The results of the tests can be found in the "doc/report" directory.
</para>
</chapter>