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:
parent
ef45d04181
commit
a499ae2273
|
@ -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" />
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue