deltaspike-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r922514 [5/11] - in /websites/staging/deltaspike/trunk/content: ./ documentation/ retired/
Date Wed, 17 Sep 2014 12:22:53 GMT
Added: websites/staging/deltaspike/trunk/content/retired/data.html
==============================================================================
--- websites/staging/deltaspike/trunk/content/retired/data.html (added)
+++ websites/staging/deltaspike/trunk/content/retired/data.html Wed Sep 17 12:22:52 2014
@@ -0,0 +1,1264 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta name="description" content="deltaspike-generate-pages">
+    <meta name="author" content="chm">
+
+    <title>Apache DeltaSpike - Data Module</title>
+
+    
+
+    
+    <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file to you under the Apache License, Version 2.0 (the &quot;License&quot;); you may not use this file except in compliance with the License.  You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License. -->
+
+    <!-- Styles -->
+    
+    <link href="./../resources/css/bootstrap.css" rel="stylesheet">    
+    <!--<link href="./../resources/css/prettify.css" rel="stylesheet" /> -->
+    <link href="./../resources/css/codehilite.css" rel="stylesheet" />
+    <link href="./../resources/css/bootstrap-responsive.css" rel="stylesheet">
+    <style type="text/css">
+        body {
+            padding-top: 60px;
+            padding-bottom: 40px;
+        }
+    </style>
+	<script type="text/javascript">
+
+	  var _gaq = _gaq || [];
+	  _gaq.push(['_setAccount', 'UA-36103647-1']);
+	  _gaq.push(['_trackPageview']);
+	
+	  (function() {
+		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+	  })();
+	
+	</script>
+</head>
+
+<body>
+    <div class="navbar navbar-fixed-top">
+        <div class="navbar-inner">
+            <div class="container">
+                <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+                    <span class="icon-bar"></span>
+                    <span class="icon-bar"></span>
+                    <span class="icon-bar"></span>
+                </a>
+                <a class="brand logocolor" href="/index.html">Apache DeltaSpike</a>
+                <div class="nav-collapse">
+                    <ul class="nav">
+                        <li class="active"><a href="./../index.html">Home</a></li>
+                        <li><a href="./../documentation.html">Documentation</a></li>
+                        <li><a href="./../source.html">Source</a></li>
+                        <li><a href="./../download.html">Download</a></li>
+                        <li><a href="./../community.html">Community</a></li>
+                        <!-- <li><a href="./../support.html">Support</a></li>  -->
+                        <li><a href="./../news.html">News</a></li>
+                        <li><a href="./../migration-guide.html">Migration</a></li>
+                    </ul>
+                </div><!--/.nav-collapse -->
+                <form id="search-form" action="http://www.google.com/search" method="get"  class="navbar-search pull-right" >
+                    <input value="deltaspike.apache.org" name="sitesearch" type="hidden"/>
+                    <input class="search-query" name="q" id="query" type="text" />
+                </form>
+            </div>
+        </div>
+    </div>
+
+    <div class="container">
+      <div class="row">
+          <div class="span12">
+              <div class="page-title">
+                <h1>Data Module</h1>
+              </div>
+              <div class="toc">
+<ul>
+<li><a href="#introduction">Introduction</a></li>
+<li><a href="#installation">Installation</a><ul>
+<li><a href="#prerequisites">Prerequisites</a></li>
+<li><a href="#maven-dependency-configuration">Maven Dependency Configuration</a></li>
+<li><a href="#setup-your-application">Setup your application</a></li>
+</ul>
+</li>
+<li><a href="#core-concepts">Core Concepts</a><ul>
+<li><a href="#repositories">Repositories</a><ul>
+<li><a href="#the-entityrepository-interface">The EntityRepository interface</a></li>
+<li><a href="#the-abstractentityrepository-class">The AbstractEntityRepository class</a></li>
+</ul>
+</li>
+<li><a href="#using-multiple-entitymanager">Using Multiple EntityManager</a></li>
+<li><a href="#other-entitymanager-methods">Other EntityManager methods</a></li>
+</ul>
+</li>
+<li><a href="#query-method-expressions">Query Method Expressions</a><ul>
+<li><a href="#using-method-expressions">Using method expressions</a></li>
+<li><a href="#query-ordering">Query Ordering</a></li>
+<li><a href="#nested-properties">Nested Properties</a></li>
+<li><a href="#query-options">Query Options</a></li>
+<li><a href="#method-prefix">Method Prefix</a></li>
+</ul>
+</li>
+<li><a href="#query-annotations">Query Annotations</a><ul>
+<li><a href="#using-query-annotations">Using Query Annotations</a></li>
+<li><a href="#annotation-options">Annotation Options</a></li>
+<li><a href="#query-options_1">Query Options</a></li>
+<li><a href="#pagination">Pagination</a></li>
+<li><a href="#bulk-operations">Bulk Operations</a></li>
+<li><a href="#optional-query-results">Optional Query Results</a></li>
+<li><a href="#zero-or-one-result">Zero or One Result</a></li>
+<li><a href="#any-result">Any Result</a></li>
+</ul>
+</li>
+<li><a href="#transactions">Transactions</a></li>
+<li><a href="#extensions">Extensions</a><ul>
+<li><a href="#query-delegates">Query Delegates</a></li>
+<li><a href="#implementing-the-query-delegate">Implementing the Query Delegate</a></li>
+</ul>
+</li>
+<li><a href="#mapping">Mapping</a><ul>
+<li><a href="#simple-mappings">Simple Mappings</a></li>
+</ul>
+</li>
+<li><a href="#jpa-criteria-api-support">JPA Criteria API Support</a><ul>
+<li><a href="#api-usage">API Usage</a></li>
+<li><a href="#joins">Joins</a></li>
+<li><a href="#boolean-operators">Boolean Operators</a></li>
+<li><a href="#selections">Selections</a></li>
+</ul>
+</li>
+<li><a href="#auditing">Auditing</a><ul>
+<li><a href="#activating-auditing">Activating Auditing</a></li>
+<li><a href="#using-auditing-annotations">Using Auditing Annotations</a><ul>
+<li><a href="#updating-timestamps">Updating Timestamps</a></li>
+<li><a href="#whos-changing-my-entities">Who's Changing My Entities?</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<hr />
+<h1 id="introduction">Introduction</h1>
+<p>The repository pattern used to be one of the core J2EE patterns and could be found in 
+most enterprise applications reading and writing data to persistent stores. 
+While the Java Persistence API (JPA) as part of Java EE 5+ has replaced many aspects of the
+repository pattern, it is still a good approach to centralize complex query logic related to 
+specific entities.</p>
+<p>The DeltaSpike Data module is intended to help you simplifying your repository layer.
+While you will have complex queries in a repository requiring your full attention,
+there will also be many simple ones often requiring boilerplate code and clutter.
+This is where the DeltaSpike Data module will help you keeping your repository lean so you 
+can focus on the though things.</p>
+<p>The code sample below will give you a quick overview on the common usage scenarios of the data module:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findByAgeBetweenAndGender</span><span class="o">(</span><span class="kt">int</span> <span class="n">minAge</span><span class="o">,</span> <span class="kt">int</span> <span class="n">maxAge</span><span class="o">,</span> <span class="n">Gender</span> <span class="n">gender</span><span class="o">);</span>
+
+    <span class="nd">@Query</span><span class="o">(</span><span class="s">&quot;select p from Person p where p.ssn = ?1&quot;</span><span class="o">)</span>
+    <span class="n">Person</span> <span class="nf">findBySSN</span><span class="o">(</span><span class="n">String</span> <span class="n">ssn</span><span class="o">);</span>
+
+    <span class="nd">@Query</span><span class="o">(</span><span class="n">named</span><span class="o">=</span><span class="n">Person</span><span class="o">.</span><span class="na">BY_FULL_NAME</span><span class="o">)</span>
+    <span class="n">Person</span> <span class="nf">findByFullName</span><span class="o">(</span><span class="n">String</span> <span class="n">firstName</span><span class="o">,</span> <span class="n">String</span> <span class="n">lastName</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>As you see in the sample, there are several usage scenarios outlined here:</p>
+<ul>
+<li>Declare a method which executes a query by simply translating its name and parameters into a query.</li>
+<li>Declare a method which automatically executes a given JPQL query string with parameters.</li>
+<li>Declare a method which automatically executes a named query with parameters. </li>
+</ul>
+<p>The implementation of the method is done automatically by the CDI extension. 
+A client can declare a dependency to the interface only. The details on how to use those 
+features are outlines in the following chapters.</p>
+<h1 id="installation">Installation</h1>
+<h2 id="prerequisites">Prerequisites</h2>
+<p>The simplest way using the DeltaSpike Data module is to run your application in a Java EE container
+supporting at least the Java EE 6 Web Profile. Other configurations like running it inside Tomcat or 
+even a Java SE application should be possible - you need to include a JPA provider as well as a CDI container
+to your application manually.</p>
+<p>Also note that in order to use abstract classes as repositories, this currently requires the presence
+of the <a href="http://www.javassist.org">javassist</a> library in your classpath.</p>
+<p><strong>CAUTION:</strong></p>
+<blockquote>
+<p>Using DeltaSpike Data in an EAR deployment is currently restricted to annotation-based entities.</p>
+</blockquote>
+<h2 id="maven-dependency-configuration">Maven Dependency Configuration</h2>
+<p>If you are using Maven as your build tool, you can add the following dependencies to your <code>pom.xml</code>
+file to include the DeltaSpike data module:</p>
+<div class="codehilite"><pre><span class="nt">&lt;dependency&gt;</span>
+    <span class="nt">&lt;groupId&gt;</span>org.apache.deltaspike.modules<span class="nt">&lt;/groupId&gt;</span>
+    <span class="nt">&lt;artifactId&gt;</span>deltaspike-data-module-api<span class="nt">&lt;/artifactId&gt;</span>
+    <span class="nt">&lt;version&gt;</span><span class="cp">${</span><span class="n">deltaspike</span><span class="o">.</span><span class="n">version</span><span class="cp">}</span><span class="nt">&lt;/version&gt;</span>
+    <span class="nt">&lt;scope&gt;</span>compile<span class="nt">&lt;/scope&gt;</span>
+<span class="nt">&lt;/dependency&gt;</span>
+<span class="nt">&lt;dependency&gt;</span>
+    <span class="nt">&lt;groupId&gt;</span>org.apache.deltaspike.modules<span class="nt">&lt;/groupId&gt;</span>
+    <span class="nt">&lt;artifactId&gt;</span>deltaspike-data-module-impl<span class="nt">&lt;/artifactId&gt;</span>
+    <span class="nt">&lt;version&gt;</span><span class="cp">${</span><span class="n">deltaspike</span><span class="o">.</span><span class="n">version</span><span class="cp">}</span><span class="nt">&lt;/version&gt;</span>
+    <span class="nt">&lt;scope&gt;</span>runtime<span class="nt">&lt;/scope&gt;</span>
+<span class="nt">&lt;/dependency&gt;</span>
+</pre></div>
+
+
+<p><strong>TIP:</strong></p>
+<blockquote>
+<p>Substitute the expression <code>${deltaspike.version}</code> with the most recent or appropriate version
+of DeltaSpike. Alternatively, you can create a Maven user-defined property to satisfy this 
+substitution so you can centrally manage the version. </p>
+</blockquote>
+<p>Including the API at compile time and only include the implementation at runtime protects you from
+inadvertantly depending on an implementation class.</p>
+<h2 id="setup-your-application">Setup your application</h2>
+<p>DeltaSpike Data requires an <code>EntityManager</code> exposed via a CDI producer - which is common practice
+in Java EE 6 applications.</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">EntityManagerProducer</span>
+<span class="o">{</span>
+
+    <span class="nd">@PersistenceUnit</span>
+    <span class="kd">private</span> <span class="n">EntityManagerFactory</span> <span class="n">emf</span><span class="o">;</span>
+
+    <span class="nd">@Produces</span> <span class="c1">// you can also make this @RequestScoped</span>
+    <span class="kd">public</span> <span class="n">EntityManager</span> <span class="nf">create</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="n">emf</span><span class="o">.</span><span class="na">createEntityManager</span><span class="o">();</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">close</span><span class="o">(</span><span class="nd">@Disposes</span> <span class="n">EntityManager</span> <span class="n">em</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">if</span> <span class="o">(</span><span class="n">em</span><span class="o">.</span><span class="na">isOpen</span><span class="o">())</span>
+        <span class="o">{</span>
+            <span class="n">em</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
+        <span class="o">}</span>
+    <span class="o">}</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>This allows the <code>EntityManager</code> to be injected over CDI instead of only being used with a
+<code>@PersistenceContext</code> annotation. Using multiple <code>EntityManager</code> is explored in more detail
+in a following section.</p>
+<p>If you use a JTA DataSource with your <code>EntityManager</code>, you also have to configure the
+<code>TransactionStrategy</code> your repositories use. Adapt your <code>beans.xml</code> for this:</p>
+<div class="codehilite"><pre><span class="nt">&lt;beans&gt;</span>
+    <span class="nt">&lt;alternatives&gt;</span>
+        <span class="nt">&lt;class&gt;</span>org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy<span class="nt">&lt;/class&gt;</span>
+    <span class="nt">&lt;/alternatives&gt;</span>
+<span class="nt">&lt;/beans&gt;</span>
+</pre></div>
+
+
+<p>You're now ready to use repositories in your application!</p>
+<h1 id="core-concepts">Core Concepts</h1>
+<h2 id="repositories">Repositories</h2>
+<p>With the DeltaSpike Data module, it is possible to make a repository out of basically any
+abstract class or interface (using a concrete class will work too, but you won't be able to use
+most of the CDI extension features). All that is required is to mark the type as such with a
+simple annotation:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span><span class="o">(</span><span class="n">forEntity</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">PersonRepository</span> <span class="o">{</span>
+    <span class="o">...</span>
+<span class="o">}</span>
+
+<span class="nd">@Repository</span><span class="o">(</span><span class="n">forEntity</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="o">{</span>
+    <span class="o">...</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The <code>@Repository</code> annotation tells the extension that this is a repository for the <code>Person</code> entity.
+Any method defined on the repository will be processed by the framework. The annotation does not
+require to set the entity class (we'll see later why) but if there are just plain classes or
+interfaces this is the only way to tell the framework what entity the repository relates to. 
+In order to simplify this, DeltaSpike Data provides several base types.</p>
+<h3 id="the-entityrepository-interface">The <code>EntityRepository</code> interface</h3>
+<p>Although mainly intended to hold complex query logic, working with both a repository and an <code>EntityManager</code>
+in the service layer might unnecessarily clutter code. In order to avoid this for the most common cases,
+DeltaSpike Data provides base types which can be used to replace the entity manager.</p>
+<p>The top base type is the <code>EntityRepository</code> interface, providing common methods used with an <code>EntityManager</code>.
+The following code shows the most important methods of the interface:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">EntityRepository</span><span class="o">&lt;</span><span class="n">E</span><span class="o">,</span> <span class="n">PK</span> <span class="kd">extends</span> <span class="n">Serializable</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="n">E</span> <span class="nf">save</span><span class="o">(</span><span class="n">E</span> <span class="n">entity</span><span class="o">);</span>
+
+    <span class="kt">void</span> <span class="nf">remove</span><span class="o">(</span><span class="n">E</span> <span class="n">entity</span><span class="o">);</span>
+
+    <span class="kt">void</span> <span class="nf">refresh</span><span class="o">(</span><span class="n">E</span> <span class="n">entity</span><span class="o">);</span>
+
+    <span class="kt">void</span> <span class="nf">flush</span><span class="o">();</span>
+
+    <span class="n">E</span> <span class="nf">findBy</span><span class="o">(</span><span class="n">PK</span> <span class="n">primaryKey</span><span class="o">);</span>
+
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="n">findAll</span><span class="o">();</span>
+
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="n">findBy</span><span class="o">(</span><span class="n">E</span> <span class="n">example</span><span class="o">,</span> <span class="n">SingularAttribute</span><span class="o">&lt;</span><span class="n">E</span><span class="o">,</span> <span class="o">?&gt;...</span> <span class="n">attributes</span><span class="o">);</span>
+
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="n">findByLike</span><span class="o">(</span><span class="n">E</span> <span class="n">example</span><span class="o">,</span> <span class="n">SingularAttribute</span><span class="o">&lt;</span><span class="n">E</span><span class="o">,</span> <span class="o">?&gt;...</span> <span class="n">attributes</span><span class="o">);</span>
+
+    <span class="n">Long</span> <span class="nf">count</span><span class="o">();</span>
+
+    <span class="n">Long</span> <span class="nf">count</span><span class="o">(</span><span class="n">E</span> <span class="n">example</span><span class="o">,</span> <span class="n">SingularAttribute</span><span class="o">&lt;</span><span class="n">E</span><span class="o">,</span> <span class="o">?&gt;...</span> <span class="n">attributes</span><span class="o">);</span>
+
+    <span class="n">Long</span> <span class="nf">countLike</span><span class="o">(</span><span class="n">E</span> <span class="n">example</span><span class="o">,</span> <span class="n">SingularAttribute</span><span class="o">&lt;</span><span class="n">E</span><span class="o">,</span> <span class="o">?&gt;...</span> <span class="n">attributes</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The concrete repository can then extend this basic interface. For our Person repository,
+this might look like the following:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="n">Person</span> <span class="nf">findBySsn</span><span class="o">(</span><span class="n">String</span> <span class="n">ssn</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p><strong>TIP:</strong></p>
+<blockquote>
+<p>Annotations on interfaces do not inherit. If the <code>EntityRepository</code> interface is extended by another
+interface adding some more common methods, it is not possible to simply add the annotation there.
+It needs to go on each concrete repository. The same is not true if a base class is introduced,
+as we see in the next chapter. </p>
+</blockquote>
+<h3 id="the-abstractentityrepository-class">The <code>AbstractEntityRepository</code> class</h3>
+<p>This class is an implementation of the <code>EntityRepository</code> interface and provides additional functionality
+when custom query logic needs also to be implemented in the repository.</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">AbstractEntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="kd">public</span> <span class="n">Person</span> <span class="nf">findBySSN</span><span class="o">(</span><span class="n">String</span> <span class="n">ssn</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="nf">typedQuery</span><span class="o">(</span><span class="s">&quot;select p from Person p where p.ssn = ?1&quot;</span><span class="o">)</span>
+                <span class="o">.</span><span class="na">setParameter</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">ssn</span><span class="o">)</span>
+                <span class="o">.</span><span class="na">getResultList</span><span class="o">();</span>
+    <span class="o">}</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="using-multiple-entitymanager">Using Multiple <code>EntityManager</code></h2>
+<p>While most applications will run just fine with a single <code>EntityManager</code>, there might be setups
+where multiple data sources are used. This can be configured with the <code>EntityManagerConfig</code> annotation:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="nd">@EntityManagerConfig</span><span class="o">(</span><span class="n">entityManagerResolver</span> <span class="o">=</span> <span class="n">CrmEntityManagerResolver</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="n">flushMode</span> <span class="o">=</span> <span class="n">FlushModeType</span><span class="o">.</span><span class="na">COMMIT</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+    <span class="o">...</span>
+<span class="o">}</span>
+
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">CrmEntityManagerResolver</span> <span class="kd">implements</span> <span class="n">EntityManagerResolver</span>
+<span class="o">{</span>
+    <span class="nd">@Inject</span> <span class="nd">@CustomerData</span> <span class="c1">// Qualifier - assumes a producer is around...</span>
+    <span class="kd">private</span> <span class="n">EntityManager</span> <span class="n">em</span><span class="o">;</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">EntityManager</span> <span class="nf">resolveEntityManager</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="n">em</span><span class="o">;</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Again, note that annotations on interfaces do not inherit, so it's not possible to create something like a base
+<code>CrmRepository</code> interface with the <code>@EntityManagerConfig</code> and then extending / implementing this interface.</p>
+<h2 id="other-entitymanager-methods">Other <code>EntityManager</code> methods</h2>
+<p>While the <code>EntityRepository</code> methods should cover most interactions normally done with an <code>EntityManager</code>,
+for some specific cases it might still be useful to have one or the other method available. For this case,
+it's possible to extend / implement the <code>EntityManagerDelegate</code> interface for repositories, which offers
+most other methods available in a JPA 2.0 <code>EntityManager</code>:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;,</span> <span class="n">EntityManagerDelegate</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span>
+<span class="o">{</span>
+    <span class="o">...</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h1 id="query-method-expressions">Query Method Expressions</h1>
+<p>Good naming is a difficult aspects in software engineering. A good method name usually makes 
+comments unnecessary and states exactly what the method does. And with method expressions, the 
+method name is actually the implementation!</p>
+<h2 id="using-method-expressions">Using method expressions</h2>
+<p>Let's start by looking at a (simplified for readability) example:</p>
+<div class="codehilite"><pre><span class="nd">@Entity</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Person</span>
+<span class="o">{</span>
+
+    <span class="nd">@Id</span> <span class="nd">@GeneratedValue</span>
+    <span class="kd">private</span> <span class="n">Long</span> <span class="n">id</span><span class="o">;</span>
+    <span class="kd">private</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
+    <span class="kd">private</span> <span class="n">Integer</span> <span class="n">age</span><span class="o">;</span>
+    <span class="kd">private</span> <span class="n">Gender</span> <span class="n">gender</span><span class="o">;</span>
+
+<span class="o">}</span>
+
+<span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findByNameLikeAndAgeBetweenAndGender</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span> 
+                              <span class="kt">int</span> <span class="n">minAge</span><span class="o">,</span> <span class="kt">int</span> <span class="n">maxAge</span><span class="o">,</span> <span class="n">Gender</span> <span class="n">gender</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Looking at the method name, this can easily be read as query all Persons which have a name like
+the given name parameter, their age is between a min and a max age and having a specific gender.
+The DeltaSpike Data module can translate method names following a given format and directly generate
+the query implementation out of it (in EBNF-like form):</p>
+<div class="codehilite"><pre><span class="p">(</span><span class="n">Entity</span><span class="o">|</span><span class="n">List</span><span class="o">&lt;</span><span class="n">Entity</span><span class="o">&gt;</span><span class="p">)</span> <span class="n">findBy</span><span class="p">(</span><span class="n">Property</span><span class="p">[</span><span class="n">Comparator</span><span class="p">]){</span><span class="n">Operator</span> <span class="n">Property</span> <span class="p">[</span><span class="n">Comparator</span><span class="p">]}</span>
+</pre></div>
+
+
+<p>Or in more concrete words:</p>
+<ul>
+<li>The query method must either return an entity or a list of entities.</li>
+<li>It must start with the <code>findBy</code> keyword (or related <code>findOptionalBy</code>, <code>findAnyBy</code>).</li>
+<li>Followed by a property of the Repository entity and an optional comparator (we'll define this later). 
+  The property will be used in the query together with the comparator. Note that the number of arguments
+  passed to the method depend on the comparator.</li>
+<li>You can add more blocks of property-comparator which have to be concatenated by a boolean operator. 
+  This is either an <code>And</code> or <code>Or</code>.</li>
+</ul>
+<p>Other assumptions taken by the expression evaluator:</p>
+<ul>
+<li>The property name starts lower cased while the property in the expression has an upper cases first character. </li>
+</ul>
+<p>Following comparators are currently supported to be used in method expressions:</p>
+<table>
+  <thead>
+    <tr>
+      <td>Name</td><td># of Arguments</td><td>Description</td>
+    </tr>
+  </thead>
+  <tr><td>Equal</td>            <td>1</td><td>Property must be equal to argument value. If the operator is omitted in the expression, this is assumed as default.</td></tr>
+  <tr><td>NotEqual</td>         <td>1</td><td>Property must be not equal to argument value.</td></tr>
+  <tr><td>Like</td>             <td>1</td><td>Property must be like the argument value. Use the %-wildcard in the argument.</td></tr>
+  <tr><td>GreaterThan</td>      <td>1</td><td>Property must be greater than argument value.</td></tr>
+  <tr><td>GreaterThanEquals</td><td>1</td><td>Property must be greater than or equal to argument value.</td></tr>
+  <tr><td>LessThan</td>         <td>1</td><td>Property must be less than argument value.</td></tr>
+  <tr><td>LessThanEquals</td>   <td>1</td><td>Property must be less than or equal to argument value.</td></tr>
+  <tr><td>Between</td>          <td>2</td><td>Property must be between the two argument values.</td></tr>
+  <tr><td>IsNull</td>           <td>0</td><td>Property must be null.</td></tr>
+  <tr><td>IsNotNull</td>        <td>0</td><td>Property must be non-null.</td></tr>
+</table>
+
+<p>Note that DeltaSpike will validate those expressions during startup, so you will notice early in case you have a typo
+in those expressions.</p>
+<h2 id="query-ordering">Query Ordering</h2>
+<p>Beside comparators it's also possible to sort queries by using the <code>OrderBy</code> keyword, followed
+by the attribute name and the direction (<code>Asc</code> or <code>Desc</code>).</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findByLastNameLikeOrderByAgeAscLastNameDesc</span><span class="o">(</span><span class="n">String</span> <span class="n">lastName</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="nested-properties">Nested Properties</h2>
+<p>To create a comparison on a nested property, the traversal parts can be separated by a <code>_</code>:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findByCompany_companyName</span><span class="o">(</span><span class="n">String</span> <span class="n">companyName</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="query-options">Query Options</h2>
+<p>DeltaSpike supports query options on method expressions. If you want to page a query,
+you can change the first result as well as the maximum number of results returned:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findByNameLike</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="nd">@FirstResult</span> <span class="kt">int</span> <span class="n">start</span><span class="o">,</span> <span class="nd">@MaxResults</span> <span class="kt">int</span> <span class="n">pageSize</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="method-prefix">Method Prefix</h2>
+<p>In case the <code>findBy</code> prefix does not comply with your team conventions, this can be adapted:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span><span class="o">(</span><span class="n">methodPrefix</span> <span class="o">=</span> <span class="s">&quot;fetchWith&quot;</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">fetchWithNameLike</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="nd">@FirstResult</span> <span class="kt">int</span> <span class="n">start</span><span class="o">,</span> <span class="nd">@MaxResults</span> <span class="kt">int</span> <span class="n">pageSize</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<h1 id="query-annotations">Query Annotations</h1>
+<p>While method expressions are fine for simple queries, they will often reach their limit once things
+get slightly more complex. Another aspect is the way you want to use JPA: The recommended approach 
+using JPA for best performance is over named queries. To help incorporate those use cases, the 
+DeltaSpike Data module supports also annotating methods for more control on the generated query.</p>
+<h2 id="using-query-annotations">Using Query Annotations</h2>
+<p>The simples way to define a specific query is by annotating a method and providing the JPQL query
+string which has to be executed. In code, this looks like the following sample:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="nd">@Query</span><span class="o">(</span><span class="s">&quot;select count(p) from Person p where p.age &gt; ?1&quot;</span><span class="o">)</span>
+    <span class="n">Long</span> <span class="nf">countAllOlderThan</span><span class="o">(</span><span class="kt">int</span> <span class="n">minAge</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The parameter binding in the query corresponds to the argument index in the method.</p>
+<p>You can also refer to a named query which is constructed and executed automatically. The <code>@Query</code>
+annotation has a named attribute which corresponds to the query name:</p>
+<div class="codehilite"><pre><span class="nd">@Entity</span>
+<span class="nd">@NamedQueries</span><span class="o">({</span>
+    <span class="nd">@NamedQuery</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">BY_MIN_AGE</span><span class="o">,</span>
+                <span class="n">query</span> <span class="o">=</span> <span class="s">&quot;select count(p) from Person p where p.age &gt; ?1 order by p.age asc&quot;</span><span class="o">)</span>
+<span class="o">})</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Person</span>
+<span class="o">{</span>
+
+    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">BY_MIN_AGE</span> <span class="o">=</span> <span class="s">&quot;person.byMinAge&quot;</span><span class="o">;</span>
+    <span class="o">...</span>
+
+<span class="o">}</span>
+
+<span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="nd">@Query</span><span class="o">(</span><span class="n">named</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">BY_MIN_AGE</span><span class="o">)</span>
+    <span class="n">Long</span> <span class="nf">countAllOlderThan</span><span class="o">(</span><span class="kt">int</span> <span class="n">minAge</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Same as before, the parameter binding corresponds to the argument index in the method. If the named
+query requires named parameters to be used, this can be done by annotating the arguments with the 
+<code>@QueryParam</code> annotation.</p>
+<p><strong>TIP:</strong></p>
+<blockquote>
+<p>Java does not preserve method parameter names (yet), that's why the annotation is needed.</p>
+</blockquote>
+<div class="codehilite"><pre><span class="nd">@NamedQuery</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">BY_MIN_AGE</span><span class="o">,</span>
+            <span class="n">query</span> <span class="o">=</span> <span class="s">&quot;select count(p) from Person p where p.age &gt; :minAge order by p.age asc&quot;</span><span class="o">)</span>
+
+<span class="o">...</span>
+
+<span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="nd">@Query</span><span class="o">(</span><span class="n">named</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">BY_MIN_AGE</span><span class="o">)</span>
+    <span class="n">Long</span> <span class="nf">countAllOlderThan</span><span class="o">(</span><span class="nd">@QueryParam</span><span class="o">(</span><span class="s">&quot;minAge&quot;</span><span class="o">)</span> <span class="kt">int</span> <span class="n">minAge</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>It is also possible to set a native SQL query in the annotation. The <code>@Query</code> annotation has a native attribute
+which flags that the query is not JPQL but plain SQL:</p>
+<div class="codehilite"><pre><span class="nd">@Entity</span>
+<span class="nd">@Table</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">&quot;PERSON_TABLE&quot;</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Person</span>
+<span class="o">{</span>
+    <span class="o">...</span>
+<span class="o">}</span>
+
+<span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="nd">@Query</span><span class="o">(</span><span class="n">value</span> <span class="o">=</span> <span class="s">&quot;SELECT * FROM PERSON_TABLE p WHERE p.AGE &gt; ?1&quot;</span><span class="o">,</span> <span class="n">isNative</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findAllOlderThan</span><span class="o">(</span><span class="kt">int</span> <span class="n">minAge</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="annotation-options">Annotation Options</h2>
+<p>Beside providing a query string or reference, the <code>@Query</code> annotation provides also two more attributes:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="nd">@Query</span><span class="o">(</span><span class="n">named</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">BY_MIN_AGE</span><span class="o">,</span> <span class="n">max</span> <span class="o">=</span> <span class="mi">10</span><span class="o">,</span> <span class="n">lock</span> <span class="o">=</span> <span class="n">LockModeType</span><span class="o">.</span><span class="na">PESSIMISTIC_WRITE</span><span class="o">)</span>
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findAllForUpdate</span><span class="o">(</span><span class="kt">int</span> <span class="n">minAge</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<table>
+  <thead>
+    <tr>
+      <td>Name</td><td>Description</td>
+    </tr>
+  </thead>
+  <tr><td>max</td> <td>Limits the number of results.</td></tr>
+  <tr><td>lock</td><td>Use a specific LockModeType to execute the query.</td></tr>
+</table>
+
+<p>Note that these options can also be applied to method expressions.</p>
+<h2 id="query-options_1">Query Options</h2>
+<p>All the query options you have seen so far are more or less static. But sometimes you might want
+to apply certain query options dynamically. For example, sorting criteria could come from a user
+selection so they cannot be known beforehand. DeltaSpike allows you to apply query options at runtime by
+using the <code>QueryResult</code> result type:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="nd">@Query</span><span class="o">(</span><span class="s">&quot;select p from Person p where p.age between ?1 and ?2&quot;</span><span class="o">)</span>
+    <span class="n">QueryResult</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findAllByAge</span><span class="o">(</span><span class="kt">int</span> <span class="n">minAge</span><span class="o">,</span> <span class="kt">int</span> <span class="n">maxAge</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Once you have obtained a <code>QueryResult</code>, you can apply further options to the query:</p>
+<div class="codehilite"><pre><span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">result</span> <span class="o">=</span> <span class="n">personRepository</span><span class="o">.</span><span class="na">findAllByAge</span><span class="o">(</span><span class="mi">18</span><span class="o">,</span> <span class="mi">65</span><span class="o">)</span>
+    <span class="o">.</span><span class="na">sortAsc</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">lastName</span><span class="o">)</span>
+    <span class="o">.</span><span class="na">sortDesc</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">age</span><span class="o">)</span>
+    <span class="o">.</span><span class="na">lockMode</span><span class="o">(</span><span class="n">LockModeType</span><span class="o">.</span><span class="na">WRITE</span><span class="o">)</span>
+    <span class="o">.</span><span class="na">hint</span><span class="o">(</span><span class="s">&quot;org.hibernate.timeout&quot;</span><span class="o">,</span> <span class="n">Integer</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="mi">10</span><span class="o">))</span>
+    <span class="o">.</span><span class="na">getResultList</span><span class="o">();</span>
+</pre></div>
+
+
+<p><strong>CAUTION:</strong></p>
+<blockquote>
+<p>Note that sorting is only applicable to method expressions or non-named queries. For named queries it might be possible, but is currently only supported for Hibernate, EclipseLink and OpenJPA.</p>
+</blockquote>
+<p>Note that the <code>QueryResult</code> return type can also be used with method expressions.</p>
+<h2 id="pagination">Pagination</h2>
+<p>We introduced the <code>QueryResult</code> type in the last chapter, which can also be used for pagination:</p>
+<div class="codehilite"><pre><span class="c1">// Query API style</span>
+<span class="n">QueryResult</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">paged</span> <span class="o">=</span> <span class="n">personRepository</span><span class="o">.</span><span class="na">findByAge</span><span class="o">(</span><span class="n">age</span><span class="o">)</span>
+    <span class="o">.</span><span class="na">maxResults</span><span class="o">(</span><span class="mi">10</span><span class="o">)</span>
+    <span class="o">.</span><span class="na">firstResult</span><span class="o">(</span><span class="mi">50</span><span class="o">);</span>
+
+<span class="c1">// or paging style</span>
+<span class="n">QueryResult</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">paged</span> <span class="o">=</span> <span class="n">personRepository</span><span class="o">.</span><span class="na">findByAge</span><span class="o">(</span><span class="n">age</span><span class="o">)</span>
+    <span class="o">.</span><span class="na">withPageSize</span><span class="o">(</span><span class="mi">10</span><span class="o">)</span> <span class="c1">// equivalent to maxResults</span>
+    <span class="o">.</span><span class="na">toPage</span><span class="o">(</span><span class="mi">5</span><span class="o">);</span>
+
+<span class="kt">int</span> <span class="n">totalPages</span> <span class="o">=</span> <span class="n">paged</span><span class="o">.</span><span class="na">countPages</span><span class="o">();</span>
+</pre></div>
+
+
+<h2 id="bulk-operations">Bulk Operations</h2>
+<p>While reading entities and updating them one by one might be fine for many use cases, applying bulk
+updates or deletes is also a common usage scenario for repositories. DeltaSpike supports this with a special
+marking annotation <code>@Modifying</code>:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="nd">@Modifying</span>
+    <span class="nd">@Query</span><span class="o">(</span><span class="s">&quot;update Person as p set p.classifier = ?1 where p.classifier = ?2&quot;</span><span class="o">)</span>
+    <span class="kt">int</span> <span class="nf">updateClassifier</span><span class="o">(</span><span class="n">Classifier</span> <span class="n">current</span><span class="o">,</span> <span class="n">Classifier</span> <span class="n">next</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Bulk operation query methods can either return void or int, which counts the number of entities affected
+by the bulk operation. </p>
+<h2 id="optional-query-results">Optional Query Results</h2>
+<p>The JPA spec requires to throw exceptions in case the <code>getSingleResult()</code> method does either return 
+no or more than one result. This can result in tedious handling with try-catch blocks or have potential 
+impact on your transaction (as the <code>RuntimeException</code> might roll it back).</p>
+<p>DeltaSpike Data gives the option to change this to the way it makes most sense for the current usecase.
+While the default behavior is still fully aligned with JPA, it's also possible to request optional query results.</p>
+<h2 id="zero-or-one-result">Zero or One Result</h2>
+<p>With this option, the query returns <code>null</code> instead of throwing a <code>NoResultException</code> when there is no 
+result returned. It's usable with method expressions, <code>Query</code> annotations and <code>QueryResult&lt;E&gt;</code> calls.</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span><span class="o">(</span><span class="n">forEntity</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span>
+<span class="o">{</span>
+
+    <span class="n">Person</span> <span class="nf">findOptionalBySsn</span><span class="o">(</span><span class="n">String</span> <span class="n">ssn</span><span class="o">);</span>
+
+    <span class="nd">@Query</span><span class="o">(</span><span class="n">named</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">BY_NAME</span><span class="o">,</span> <span class="n">singleResult</span> <span class="o">=</span> <span class="n">SingleResultType</span><span class="o">.</span><span class="na">OPTIONAL</span><span class="o">)</span>
+    <span class="n">Person</span> <span class="nf">findByName</span><span class="o">(</span><span class="n">String</span> <span class="n">firstName</span><span class="o">,</span> <span class="n">String</span> <span class="n">lastName</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>For method expressions, the <code>findOptionalBy</code> prefix can be used. For <code>@Query</code> annotations, the <code>singleResult</code>
+attribute can be overridden with the <code>SingleResultType.OPTIONAL</code> enum.</p>
+<p>In case the query returns more than one result, a <code>NonUniqueResultException</code> is still thrown.</p>
+<h2 id="any-result">Any Result</h2>
+<p>If the caller does not really mind what kind if result is returned, it's also possible to request any 
+result from the query. If there is no result, same as for optional queries <code>null</code> is returned. In case 
+there is more than one result, any result is returned, or more concretely the first result out of the 
+result list.</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span><span class="o">(</span><span class="n">forEntity</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span>
+<span class="o">{</span>
+
+    <span class="n">Person</span> <span class="nf">findAnyByLastName</span><span class="o">(</span><span class="n">String</span> <span class="n">lastName</span><span class="o">);</span>
+
+    <span class="nd">@Query</span><span class="o">(</span><span class="n">named</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">BY_NAME</span><span class="o">,</span> <span class="n">singleResult</span> <span class="o">=</span> <span class="n">SingleResultType</span><span class="o">.</span><span class="na">ANY</span><span class="o">)</span>
+    <span class="n">Person</span> <span class="nf">findByName</span><span class="o">(</span><span class="n">String</span> <span class="n">firstName</span><span class="o">,</span> <span class="n">String</span> <span class="n">lastName</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>For method expressions, the <code>findAnyBy</code> prefix can be used. For <code>@Query</code> annotations, the <code>singleResult</code>
+attribute can be overridden with the <code>SingleResultType.ANY</code> enum.</p>
+<p>This option will not throw an exception.</p>
+<h1 id="transactions">Transactions</h1>
+<p>If you call any method expression, <code>@Query</code>-annotated method or a method from the <code>EntityRepository</code>, the 
+repository will figure out if a transaction is needed or not, and if so, if there is already one ongoing.
+The Data module uses the <code>TransactionStrategy</code> provided by the <a href="http://deltaspike.apache.org/jpa" title="JPA module">JPA Module</a> for this. See the JPA module
+documentation for more details.</p>
+<p><strong>CAUTION:</strong></p>
+<blockquote>
+<p>Some containers do not support <code>BeanManagedUserTransactionStrategy</code>! As JTA has still some portability
+issues even in Java EE 7, it might be required that you implement your own <code>TransactionStrategy</code>.
+We will think about providing an acceptable solution for this.</p>
+</blockquote>
+<p><strong>CAUTION:</strong></p>
+<blockquote>
+<p>Annotating Repository methods with <code>@Transactional</code> is not yet supported, but will follow.</p>
+</blockquote>
+<p>If you need to open a transaction on a concrete repository method, we currently recommend creating an extension
+(see next chapter) which uses <code>@Transactional</code> and might look like the following sample. </p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">TxExtension</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="kd">implements</span> <span class="n">TxRepository</span> <span class="c1">// this is your extension interface</span>
+<span class="o">{</span>
+    <span class="nd">@Inject</span>
+    <span class="kd">private</span> <span class="n">EntityManager</span> <span class="n">em</span><span class="o">;</span>
+
+    <span class="nd">@Override</span> <span class="nd">@Transactional</span>
+    <span class="kd">public</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="n">transactional</span><span class="o">(</span><span class="n">ListResultCallback</span> <span class="n">callback</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="n">callback</span><span class="o">.</span><span class="na">execute</span><span class="o">();</span>
+    <span class="o">}</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Repositories can then implement the <code>TxRepository</code> interface and call their queries in the
+<code>transactional</code> method (where the callback implementation can be e.g. in an anonymous class).</p>
+<h1 id="extensions">Extensions</h1>
+<h2 id="query-delegates">Query Delegates</h2>
+<p>While repositories defines several base interfaces, there might still be the odd convenience
+method that is missing. This is actually intentional - things should not get overloaded for each and
+every use case. That's why in DeltaSpike you can define your own reusable methods.</p>
+<p>For example, you might want to use the QueryDsl library in your repositories:</p>
+<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">com.mysema.query.jpa.impl.JPAQuery</span><span class="o">;</span>
+
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">QueryDslSupport</span>
+<span class="o">{</span>
+    <span class="n">JPAQuery</span> <span class="nf">jpaQuery</span><span class="o">();</span>
+<span class="o">}</span>
+
+<span class="nd">@Repository</span><span class="o">(</span><span class="n">forEntity</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">QueryDslSupport</span>
+<span class="o">{</span>
+   <span class="o">...</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="implementing-the-query-delegate">Implementing the Query Delegate</h2>
+<p>The first step is to define an interface which contains the extra methods for your repositories
+(as shown above):</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">QueryDslSupport</span>
+<span class="o">{</span>
+    <span class="n">JPAQuery</span> <span class="nf">jpaQuery</span><span class="o">();</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>As a next step, you need to provide an implementation for this interface once. It's also important
+that this implementation implements the <code>DelegateQueryHandler</code> interface (don't worry, this is just
+an empty marker interface):</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">QueryDslRepositoryExtension</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="kd">implements</span> <span class="n">QueryDslSupport</span><span class="o">,</span> <span class="n">DelegateQueryHandler</span>
+<span class="o">{</span>
+
+    <span class="nd">@Inject</span>
+    <span class="kd">private</span> <span class="n">QueryInvocationContext</span> <span class="n">context</span><span class="o">;</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">JPAQuery</span> <span class="nf">jpaQuery</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="k">new</span> <span class="nf">JPAQuery</span><span class="o">(</span><span class="n">context</span><span class="o">.</span><span class="na">getEntityManager</span><span class="o">());</span>
+    <span class="o">}</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>As you see in the sample, you can inject a <code>QueryInvocationContext</code> which contains utility methods
+like accessing the current <code>EntityManager</code> and entity class.       </p>
+<p>Note that, if you define multiple extensions with equivalent method signatures, there is no specific
+order in which the implementation is selected.</p>
+<h1 id="mapping">Mapping</h1>
+<p>While repositories are primarily intended to work with Entities, it might be preferable in some
+cases to have an additional mapping layer on top of them, e.g. because the Entities are quite complex
+but the service layer needs only a limited view on it, or because the Entities are exposed over a
+remote interface and there should not be a 1:1 view on the domain model.</p>
+<p>DeltaSpike Data allows to directly plugin in such a mapping mechanism without the need to specify additional
+mapping methods:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span><span class="o">(</span><span class="n">forEntity</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="nd">@MappingConfig</span><span class="o">(</span><span class="n">PersonDtoMapper</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span>
+<span class="o">{</span>
+
+    <span class="n">PersonDto</span> <span class="nf">findBySsn</span><span class="o">(</span><span class="n">String</span> <span class="n">ssn</span><span class="o">);</span>
+
+    <span class="n">List</span><span class="o">&lt;</span><span class="n">PersonDto</span><span class="o">&gt;</span> <span class="n">findByLastName</span><span class="o">(</span><span class="n">String</span> <span class="n">lastName</span><span class="o">);</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The <code>PersonDtoMapper</code> class has to implement the <code>QueryInOutMapper</code> interface:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">PersonDtoMapper</span> <span class="kd">implements</span> <span class="n">QueryInOutMapper</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">Object</span> <span class="nf">mapResult</span><span class="o">(</span><span class="n">Person</span> <span class="n">result</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="o">...</span> <span class="c1">// converts Person into a PersonDto</span>
+    <span class="o">}</span>
+    <span class="o">...</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">Object</span> <span class="nf">mapResultList</span><span class="o">(</span><span class="n">List</span><span class="o">&lt;</span><span class="n">Simple</span><span class="o">&gt;</span> <span class="n">result</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="o">...</span> <span class="c1">// result lists can also be mapped into something different</span>
+            <span class="c1">// than a collection.</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">mapsParameter</span><span class="o">(</span><span class="n">Object</span> <span class="n">parameter</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="n">parameter</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="o">(</span>
+                <span class="n">parameter</span> <span class="k">instanceof</span> <span class="n">PersonDto</span> <span class="o">||</span> <span class="n">parameter</span> <span class="k">instanceof</span> <span class="n">PersonId</span><span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">Object</span> <span class="nf">mapParameter</span><span class="o">(</span><span class="n">Object</span> <span class="n">parameter</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="o">...</span> <span class="c1">// converts query parameters if required</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The mapper can also be used to transform query parameters. Parameters are converted before
+executing queries and calling repository extensions.</p>
+<p>Note that those mapper classes are treated as CDI Beans, so it is possible to use injection
+in those beans (you might e.g. inject an <code>EntityManager</code> or other mappers). As the <code>@MappingConfig</code>
+refers to the mapper class directly, the mapper must be uniquely identifiable by its class.</p>
+<p>It's also possible to combine mappings with the base Repository classes:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span><span class="o">(</span><span class="n">forEntity</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="nd">@MappingConfig</span><span class="o">(</span><span class="n">PersonDtoMapper</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">EntityRepository</span><span class="o">&lt;</span><span class="n">PersonDto</span><span class="o">,</span> <span class="n">PersonId</span><span class="o">&gt;</span>
+<span class="o">{</span>
+    <span class="o">...</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>In this case, the <code>forEntity</code> attribute in the <code>@Repository</code> annotation is mandatory. Also it is up
+to the mapper to convert parameters correctly (in this example, a conversion from a <code>PersonDto</code>
+parameter to <code>Person</code> entity and from <code>PersonId</code> to <code>Long</code> is necessary).</p>
+<h2 id="simple-mappings">Simple Mappings</h2>
+<p>In many cases it's just required to map a DTO object back and forth. For this case, the <code>SimpleQueryInOutMapperBase</code> class 
+can be subclassed, which only requires to override two methods:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">PersonMapper</span> <span class="kd">extends</span> <span class="n">SimpleQueryInOutMapperBase</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">PersonDto</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">protected</span> <span class="n">Object</span> <span class="nf">getPrimaryKey</span><span class="o">(</span><span class="n">PersonDto</span> <span class="n">dto</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="n">dto</span><span class="o">.</span><span class="na">getId</span><span class="o">();</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">protected</span> <span class="n">PersonDto</span> <span class="nf">toDto</span><span class="o">(</span><span class="n">Person</span> <span class="n">entity</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="o">...</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">protected</span> <span class="n">Person</span> <span class="nf">toEntity</span><span class="o">(</span><span class="n">Person</span> <span class="n">entity</span><span class="o">,</span> <span class="n">PersonDto</span> <span class="n">dto</span><span class="o">)</span> <span class="o">{</span>
+        <span class="o">...</span>
+        <span class="k">return</span> <span class="n">entity</span><span class="o">;</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The first method, <code>getPrimaryKey</code>, identifies the primary key of an incoming DTO (this might need mapping too).
+If there is a primary key in the DTO, Data tries to retrieve the Entity and feed it to the <code>toEntity</code> method,
+so the entity to be mapped is <strong>attached to the persistence context</strong>. If there is no primary key, a new 
+instance of the Entity is created. In any case, there is no need to map the primary key to the entity (it either
+does not exist or is already populated for an existing entity).</p>
+<h1 id="jpa-criteria-api-support">JPA Criteria API Support</h1>
+<p>Beside automatic query generation, the DeltaSpike Data module also provides a DSL-like API to create JPA 2 Criteria queries.
+It takes advantage of the JPA 2 meta model, which helps creating type safe queries.</p>
+<p><strong>TIP:</strong></p>
+<blockquote>
+<p>The JPA meta model can easily be generated with an annotation processor. Hibernate or EclipseLink 
+provide such a processor, which can be integrated into your compile and build cycle.</p>
+</blockquote>
+<p>Note that this criteria API is not intended to replace the standard criteria API - it's rather a utility
+API that should make life easier on the most common cases for a custom query. The JPA criteria API's 
+strongest point is certainly its type safety - which comes at the cost of readability. We're trying to 
+provide a middle way here. A less powerful API, but still type safe and readable.</p>
+<h2 id="api-usage">API Usage</h2>
+<p>The API is centered around the Criteria class and is targeted to provide a fluent interface
+to write criteria queries:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span><span class="o">(</span><span class="n">forEntity</span> <span class="o">=</span> <span class="n">Person</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">PersonRepository</span> <span class="kd">implements</span> <span class="n">CriteriaSupport</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="kd">public</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findAdultFamilyMembers</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span> <span class="n">Integer</span> <span class="n">minAge</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="nf">criteria</span><span class="o">()</span>
+                <span class="o">.</span><span class="na">like</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">name</span><span class="o">,</span> <span class="s">&quot;%&quot;</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s">&quot;%&quot;</span><span class="o">)</span>
+                <span class="o">.</span><span class="na">gtOrEq</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">age</span><span class="o">,</span> <span class="n">minAge</span><span class="o">)</span>
+                <span class="o">.</span><span class="na">eq</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">validated</span><span class="o">,</span> <span class="n">Boolean</span><span class="o">.</span><span class="na">TRUE</span><span class="o">)</span>
+                <span class="o">.</span><span class="na">orderDesc</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">age</span><span class="o">)</span>
+                <span class="o">.</span><span class="na">getResultList</span><span class="o">();</span>
+    <span class="o">}</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Following comparators are supported by the API:</p>
+<table>
+  <thead>
+    <tr>
+      <td>Name</td><td>Description</td>
+    </tr>
+  </thead>
+  <tr><td>.eq(..., ...)  </td><td>Property value must be equal to the given value  </td></tr>
+  <tr><td>.in(..., ..., ..., ...)  </td><td>Property value must be in one of the given values.  </td></tr>
+  <tr><td>.notEq(..., ...)  </td><td>Negates equality  </td></tr>
+  <tr><td>.like(..., ...)  </td><td>A SQL `like` equivalent comparator. Use % on the value.  </td></tr>
+  <tr><td>.notLike(..., ...)  </td><td>Negates the like value  </td></tr>
+  <tr><td>.lt(..., ...)  </td><td>Property value must be less than the given value.  </td></tr>
+  <tr><td>.ltOrEq(..., ...)  </td><td>Property value must be less than or equal to the given value.  </td></tr>
+  <tr><td>.gt(..., ...)  </td><td>Property value must be greater than the given value.  </td></tr>
+  <tr><td>.ltOrEq(..., ...)  </td><td>Property value must be greater than or equal to the given value.  </td></tr>
+  <tr><td>.between(..., ..., ...)  </td><td>Property value must be between the two given values. </td></tr>
+  <tr><td>.isNull(...)  </td><td>Property must be `null`</td></tr>
+  <tr><td>.isNotNull(...)  </td><td>Property must be non-`null`  </td></tr>
+  <tr><td>.isEmpty(...)  </td><td>Collection property must be empty</td></tr>
+  <tr><td>.isNotEmpty(...)  </td><td>Collection property must be non-empty</td></tr>
+</table>
+
+<p>The query result can be modified with the following settings:</p>
+<table>
+  <thead>
+    <tr>
+      <td>Name</td><td>Description</td>
+    </tr>
+  </thead>
+  <tr><td>.orderAsc(...)</td><td>Sorts the result ascending by the given property. Note that this can be applied to several properties</td></tr>
+  <tr><td>.orderDesc(...)</td><td>Sorts the result descending by the given property. Note that this can be applied to several properties</td></tr>
+  <tr><td>.distinct()</td><td>Sets distinct to true on the query.</td></tr>
+</table>
+
+<p>Once all comparators and query options are applied, the <code>createQuery()</code> method is called. 
+This creates a JPA TypedQuery object for the repository entity. If required, further processing can be applied here.</p>
+<h2 id="joins">Joins</h2>
+<p>For simple cases, restricting on the repository entity only works out fine, but once the Data model
+gets more complicated, the query will have to consider relations to other entities. The module's criteria
+API therefore supports joins as shown in the sample below:</p>
+<div class="codehilite"><pre><span class="nd">@Repository</span>
+<span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">AbstractEntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="kd">public</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findByCompanyName</span><span class="o">(</span><span class="n">String</span> <span class="n">companyName</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="nf">criteria</span><span class="o">()</span>
+                <span class="o">.</span><span class="na">join</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">company</span><span class="o">,</span>
+                    <span class="n">where</span><span class="o">(</span><span class="n">Company</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+                        <span class="o">.</span><span class="na">eq</span><span class="o">(</span><span class="n">Company_</span><span class="o">.</span><span class="na">name</span><span class="o">,</span> <span class="n">companyName</span><span class="o">)</span>
+                <span class="o">)</span>
+                <span class="o">.</span><span class="na">eq</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">validated</span><span class="o">,</span> <span class="n">Boolean</span><span class="o">.</span><span class="na">TRUE</span><span class="o">)</span>
+                <span class="o">.</span><span class="na">getResultList</span><span class="o">();</span>
+    <span class="o">}</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Beside the inner and outer joins, also fetch joins are supported. Those are slighly simpler as seen in the next sample:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">AbstractEntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="kd">public</span> <span class="n">Person</span> <span class="nf">findBySSN</span><span class="o">(</span><span class="n">String</span> <span class="n">ssn</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="nf">criteria</span><span class="o">()</span>
+                <span class="o">.</span><span class="na">fetch</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">familyMembers</span><span class="o">)</span>
+                <span class="o">.</span><span class="na">eq</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">ssn</span><span class="o">,</span> <span class="n">ssn</span><span class="o">)</span>
+                <span class="o">.</span><span class="na">distinct</span><span class="o">()</span>
+                <span class="o">.</span><span class="na">getSingleResult</span><span class="o">();</span>
+    <span class="o">}</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="boolean-operators">Boolean Operators</h2>
+<p>By default, all query operators are concatenated as an and conjunction to the query. The DeltaSpike
+criteria API also allows to add groups of disjunctions.</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">AbstractEntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="kd">public</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="n">findAdults</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="nf">criteria</span><span class="o">()</span>
+                <span class="o">.</span><span class="na">or</span><span class="o">(</span>
+                    <span class="n">criteria</span><span class="o">().</span>
+                        <span class="o">.</span><span class="na">gtOrEq</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">age</span><span class="o">,</span> <span class="mi">18</span><span class="o">)</span>
+                        <span class="o">.</span><span class="na">eq</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">origin</span><span class="o">,</span> <span class="n">Country</span><span class="o">.</span><span class="na">SWITZERLAND</span><span class="o">),</span>
+                    <span class="n">criteria</span><span class="o">().</span>
+                        <span class="o">.</span><span class="na">gtOrEq</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">age</span><span class="o">,</span> <span class="mi">21</span><span class="o">)</span>
+                        <span class="o">.</span><span class="na">eq</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">origin</span><span class="o">,</span> <span class="n">Country</span><span class="o">.</span><span class="na">USA</span><span class="o">)</span>
+                <span class="o">)</span>
+                <span class="o">.</span><span class="na">getResultList</span><span class="o">();</span>
+    <span class="o">}</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="selections">Selections</h2>
+<p>It might not always be appropriate to retrieve full entities - you might also be interested
+in scalar values or by modified entity attributes. The Criteria interface allows this with the
+selection method:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">AbstractEntityRepository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span>
+<span class="o">{</span>
+
+    <span class="kd">public</span> <span class="n">Statistics</span> <span class="nf">ageStatsFor</span><span class="o">(</span><span class="n">Segment</span> <span class="n">segment</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="nf">criteria</span><span class="o">()</span>
+                 <span class="o">.</span><span class="na">select</span><span class="o">(</span><span class="n">Statistics</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="n">avg</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">age</span><span class="o">),</span> <span class="n">min</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">age</span><span class="o">),</span> <span class="n">max</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">age</span><span class="o">))</span>
+                 <span class="o">.</span><span class="na">eq</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">segment</span><span class="o">,</span> <span class="n">segment</span><span class="o">)</span>
+                 <span class="o">.</span><span class="na">getSingleResult</span><span class="o">();</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">Object</span><span class="o">[]&gt;</span> <span class="n">personViewForFamily</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="nf">criteria</span><span class="o">()</span>
+                 <span class="o">.</span><span class="na">select</span><span class="o">(</span><span class="n">upper</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">name</span><span class="o">),</span> <span class="n">attribute</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">age</span><span class="o">),</span> <span class="n">substring</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">firstname</span><span class="o">,</span> <span class="mi">1</span><span class="o">))</span>
+                 <span class="o">.</span><span class="na">like</span><span class="o">(</span><span class="n">Person_</span><span class="o">.</span><span class="na">name</span><span class="o">,</span> <span class="n">name</span><span class="o">)</span>
+                 <span class="o">.</span><span class="na">getResultList</span><span class="o">();</span>
+    <span class="o">}</span>
+
+<span class="o">}</span>
+</pre></div>
+
+
+<p>There are also several functions supported which can be used in the selection clause:</p>
+<table>
+  <thead>
+    <tr>
+      <td>Name</td><td>Description</td>
+    </tr>
+  </thead>
+  <tr><td>abs(...)</td><td>Absolute value. Applicable to Number attributes.</td></tr>
+  <tr><td>avg(...)</td><td>Average value. Applicable to Number attributes.</td></tr>
+  <tr><td>count(...) </td><td>Count function. Applicable to Number attributes.</td></tr>
+  <tr><td>max(...) </td><td>Max value. Applicable to Number attributes.</td></tr>
+  <tr><td>min(...) </td><td>Min value. Applicable to Number attributes.</td></tr>
+  <tr><td>modulo(...)</td><td>Modulo function. Applicable to Integer attributes.</td></tr>
+  <tr><td>neg(...)</td><td>Negative value. Applicable to Number attributes.</td></tr>
+  <tr><td>sum(...) </td><td>Sum function. Applicable to Number attributes.</td></tr>
+  <tr><td>lower(...)</td><td>String to lowercase. Applicable to String attributes.</td></tr>
+  <tr><td>substring(int from, ...)</td><td>Substring starting from. Applicable to String attributes.</td></tr>
+  <tr><td>substring(int from, int to, ...)</td><td>Substring starting from ending to. Applicable to String attributes.</td></tr>
+  <tr><td>upper(...) </td><td>String to uppercase. Applicable to String attributes.</td></tr>
+  <tr><td>currDate() </td><td>The DB sysdate. Returns a Date object.</td></tr>
+  <tr><td>currTime() </td><td>The DB sysdate. Returns a Time object.</td></tr>
+  <tr><td>currTStamp()</td><td>The DB sysdate. Returns a Timestamp object. </td></tr>
+</table>
+
+<h1 id="auditing">Auditing</h1>
+<p>A common requirement for entities is tracking what is being done with them. DeltaSpike provides
+a convenient way to support this requirement.</p>
+<p><strong>TIP:</strong></p>
+<blockquote>
+<p>DeltaSpike does not support creating revisions of entities. If this is a requirement for your audits, 
+have a look at Hibernate Envers.</p>
+</blockquote>
+<h2 id="activating-auditing">Activating Auditing</h2>
+<p>DeltaSpike uses an entity listener to update auditing data before entities get created or update.
+The entity listener must be activated before it can be used. This can either be done globally for
+all entities of a persistent unit or per entity.</p>

[... 136 lines stripped ...]


Mime
View raw message