HHH-6036: Moving the "query" chapter of Envers docs
This commit is contained in:
parent
9758c63354
commit
a16177035a
|
@ -379,6 +379,197 @@ public class ExampleListener implements RevisionListener {
|
|||
|
||||
</section>
|
||||
|
||||
<section id="envers-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>
|
||||
|
||||
<para>
|
||||
In the future, queries will be improved both in terms of speed and possibilities, when using the valid-time
|
||||
audit strategy, that is when storing both start and end revisions for entities. See
|
||||
<xref linkend="configuration"/>.
|
||||
</para>
|
||||
|
||||
<section 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>
|
||||
|
||||
</section>
|
||||
|
||||
<section 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>
|
||||
<para>
|
||||
using <literal>AuditEntity.revisionNumber()</literal> you can specify constraints, projections
|
||||
and order on the revision number, in which the audited entity was modified
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
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
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>AuditEntity.revisionType()</literal> gives you access as above to the type of
|
||||
the revision (ADD, MOD, DEL).
|
||||
</para>
|
||||
</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>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Understanding the Envers Schema</title>
|
||||
|
||||
|
|
Loading…
Reference in New Issue