You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/09/26 08:20:22 UTC

[01/10] cayenne git commit: CYA_2173 Update fluent query API documentation

Repository: cayenne
Updated Branches:
  refs/heads/STABLE-4.0 25f3ba07e -> d5a181fff


http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries.xml b/docs/docbook/cayenne-guide/src/docbkx/queries.xml
index 37254d4..28b2993 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/queries.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries.xml
@@ -14,7 +14,7 @@
     the specific language governing permissions and limitations under the
     License.
 -->
-<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude"
     version="5.0" xml:id="queries">
     <title>Queries</title>
     <para>Queries are Java objects used by the application to communicate with the database. Cayenne
@@ -38,622 +38,18 @@
         "data row" is often used to describe such a map). They can potentially be converted to
         objects, however it may take a considerable effort to do so. Native queries are also less
         (if at all) portable across databases than object queries. </para>
-    <section xml:id="selectquery">
-        <title>ObjectSelect</title>
-        <para>
-            <emphasis role="italic">ObjectSelect supersedes older SelectQuery. SelectQuery is still
-                available and supported. </emphasis>
-        </para>
-        <para>ObjectSelect is the most commonly used query in Cayenne applications. This may be the
-            only query you will ever need. It returns a list of persistent objects (or data rows) of
-            a certain type specified in the
-            query:<programlisting language="java">List&lt;Artist> objects = ObjectSelect.query(Artist.class).select(context);</programlisting>This
-            returned all rows in the "ARTIST" table. If the logs were turned on, you might see the
-            following SQL
-            printed:<screen>INFO: SELECT t0.DATE_OF_BIRTH, t0.NAME, t0.ID FROM ARTIST t0
-INFO: === returned 5 row. - took 5 ms.</screen></para>
-        <para>This SQL was generated by Cayenne from the ObjectSelect above. ObjectSelect can have a
-            qualifier to select only the data matching specific criteria. Qualifier is simply an
-            Expression (Expressions where discussed in the previous chapter), appended to the query
-            using "where" method. If you only want artists whose name begins with 'Pablo', you might
-            use the following qualifier expression:
-            <programlisting language="java">List&lt;Artist> objects = ObjectSelect.query(Artist.class)
-        .where(Artist.NAME.like("Pablo%"))
-        .select(context);</programlisting>The
-            SQL will look different this
-            time:<screen>INFO: SELECT t0.DATE_OF_BIRTH, t0.NAME, t0.ID FROM ARTIST t0 WHERE t0.NAME LIKE ?
-[bind: 1->NAME:'Pablo%']
-INFO: === returned 1 row. - took 6 ms.</screen></para>
-        <para>ObjectSelect allows to assemble qualifier from parts, using "and" and "or" method to
-            chain then
-            together:<programlisting language="java">List&lt;Artist> objects = ObjectSelect.query(Artist.class)
-        .where(Artist.NAME.like("A%"))
-        .and(Artist.DATE_OF_BIRTH.gt(someDate)
-        .select(context);</programlisting></para>
-        <para>To order the results of ObjectSelect, one or more orderings can be
-            applied:<programlisting language="java">List&lt;Artist> objects = ObjectSelect.query(Artist.class)
-        .addOrderBy(Artist.DATE_OF_BIRTH.desc())
-        .addOrderBy(Artist.NAME.asc())
-        .select(context);</programlisting></para>
-        <para>There's a number of other useful methods in ObjectSelect that define what to select
-            and how to optimize database interaction (prefetching, caching, fetch offset and limit,
-            pagination, etc.). Some of them are discussed in separate chapters on caching and
-            performance optimization. Others are fairly self-explanatory. Please check the API docs
-            for the full extent of the ObjectSelect features.</para>
-    </section>
-    <section xml:id="ejbqlquery">
-        <title>EJBQLQuery</title>
-        <para>EJBQLQuery was created as a part of an experiment in adopting some of Java Persistence
-            API (JPA) approaches in Cayenne. It is a parameterized object query that is created from
-            query String. A String used to build EJBQLQuery must conform to JPQL (JPA query
-            language):<programlisting language="java">EJBQLQuery query = new EJBQLQuery("select a FROM Artist a");</programlisting></para>
-        <para>JPQL details can be found in any JPA manual. Here we'll mention only how this fits
-            into Cayenne and what are the differences between EJBQL and other Cayenne
-            queries.</para>
-        <para>Although most frequently EJBQLQuery is used as an alternative to SelectQuery, there
-            are also DELETE and UPDATE varieties available. <note>
-                <para>As of this version of Cayenne, DELETE and UPDATE do not change the state of
-                    objects in the ObjectContext. They are run directly against the database
-                    instead. </para>
-            </note><programlisting language="java">EJBQLQuery select = new EJBQLQuery("select a FROM Artist a WHERE a.name = 'Salvador Dali'");
-List&lt;Artist> artists = context.performQuery(select);</programlisting><programlisting language="java">EJBQLQuery delete = new EJBQLQuery("delete from Painting");
-context.performGenericQuery(delete);</programlisting><programlisting language="java">EJBQLQuery update = new EJBQLQuery("UPDATE Painting AS p SET p.name = 'P2' WHERE p.name = 'P1'");
-context.performGenericQuery(update);</programlisting>In
-            most cases SelectQuery is preferred to EJBQLQuery, as it is API-based, and provides you
-            with better compile-time checks. However sometimes you may want a completely scriptable
-            object query. This is when you might prefer EJBQL. A more practical reason for picking
-            EJBQL over SelectQuery though is that the former offers some extra selecting
-            capabilities, namely aggregate functions and
-            subqueries:<programlisting language="java">EJBQLQuery query = new EJBQLQuery("select a, COUNT(p) FROM Artist a JOIN a.paintings p GROUP BY a");
-List&lt;Object[]> result = context.performQuery(query);
-for(Object[] artistWithCount : result) {
-    Artist a = (Artist) artistWithCount[0];
-    int hasPaintings = (Integer) artistWithCount[1];
-}</programlisting>This
-            also demonstrates a previously unseen type of select result - a List of Object[]
-            elements, where each entry in an Object[] is either a DataObject or a scalar, depending
-            on the query SELECT clause. A result can also be a list of
-            scalars:<programlisting language="java">EJBQLQuery query = new EJBQLQuery("select a.name FROM Artist a");
-List&lt;String> names = context.performQuery(query);</programlisting>
 
-            EJBQLQuery supports an "IN" clause with three different usage-patterns.  The following
-            example would require three individual positional parameters (named
-            parameters could also have been used) to be supplied.
-
-            <programlisting language="sql">select p from Painting p where p.paintingTitle in (?1,?2,?3)</programlisting>
-
-            The following example requires a single positional parameter to be supplied.  The
-            parameter can be any concrete implementation of the java.util.Collection interface such as
-            java.util.List or java.util.Set.
-
-            <programlisting language="sql">select p from Painting p where p.paintingTitle in ?1</programlisting>
-
-            The following example is functionally identical to the one prior.
-
-            <programlisting language="sql">select p from Painting p where p.paintingTitle in (?1)</programlisting>
-
-            </para>
-            <para>
-                It is <link linkend="expressions-to-ejbql">possible to convert</link>
-                an <link linkend="expressions">Expression</link>
-                object used with a <link linkend="selectquery">SelectQuery</link>
-                to EJBQL.  Use the Expression#appendAsEJBQL methods for this purpose.
-            </para>
-            <para>
-            While
-            Cayenne Expressions discussed previously can be thought of as identical to JPQL WHERE
-            clause, and indeed they are very close, there are a few noteable differences:
-            <itemizedlist>
-                <listitem>
-                    <para>Null handling: SelectQuery would translate the expressions matching NULL
-                        values to the corresponding "X IS NULL" or "X IS NOT NULL" SQL syntax.
-                        EJBQLQuery on the other hand requires explicit "IS NULL" (or "IS NOT NULL")
-                        syntax to be used, otherwise the generated SQL will look like "X = NULL" (or
-                        "X &lt;> NULL"), which will evaluate differently.</para>
-                </listitem>
-                <listitem>
-                    <para>Expression Parameters: SelectQuery uses "$" to denote named parameters
-                        (e.g. "$myParam"), while EJBQL uses ":" (e.g. ":myParam"). Also EJBQL
-                        supports positional parameters denoted by the question mark: "?3".</para>
-                </listitem>
-            </itemizedlist>
-        </para>
-    </section>
-    <section xml:id="sqltemplate">
-        <title>SQLTemplate</title>
-        <para>SQLTemplate is a query that allows to run native SQL from a Cayenne application. It
-            comes handy when the standard ORM concepts are not sufficient for a given query or an
-            update. SQL is too powerful and allows to manipulate data in ways that are not easily
-            described as a graph of related entities. Cayenne acknowledges this fact and provides
-            this facility to execute SQL, mapping the result to objects when possible. Here are
-            examples of selecting and non-selecting
-            SQLTemplates:<programlisting language="java">SQLTemplate select = new SQLTemplate(Artist.class, "select * from ARTIST"); 
-List&lt;Artist> result = context.performQuery(select);</programlisting><programlisting language="java">SQLTemplate update = new SQLTemplate(Artist.class, "delete from ARTIST");
-QueryResponse response = context.performGenericQuery(update);</programlisting></para>
-        <para>Cayenne doesn't make any attempt to make sense of the SQL semantics, so it doesn't
-            know whether a given query is performing a select or update, etc. It is the the user's
-            decision to run a given query as a selecting or "generic".</para>
-        <para>
-            <note>
-                <para>Any data modifications done to DB as a result of SQLTemplate execution do not
-                    change the state of objects in the ObjectContext. So some objects in the context
-                    may become stale as a result.</para>
-            </note>
-        </para>
-        <para>Another point to note is that the first argument to the SQLTemplate constructor - the
-            Java class - has the same meaning as in SelectQuery only when the result can be
-            converted to objects (e.g. when this is a selecting query and it is selecting all
-            columns from one table). In this case it denotes the "root" entity of this query result.
-            If the query does not denote a single entity result, this argument is only used for
-            query routing, i.e. determining which database it should be run against. You are free to
-            use any persistent class or even a DataMap instance in such situation. It will work as
-            long as the passed "root" maps to the same database as the current query.</para>
-        <para>To achieve interoperability between mutliple RDBMS a user can specify multiple SQL
-            statements for the same SQLTemplate, each corresponding to a native SQL dialect. A key
-            used to look up the right dialect during execution is a fully qualified class name of
-            the corresponding DbAdapter. If no DB-specific statement is present for a given DB, a
-            default generic statement is used. E.g. in all the examples above a default statement
-            will be used regardless of the runtime database. So in most cases you won't need to
-            explicitly "translate" your SQL to all possible dialects. Here is how this works in
-            practice:<programlisting language="java">SQLTemplate select = new SQLTemplate(Artist.class, "select * from ARTIST"); 
-
-// For Postgres it would be nice to trim padding of all CHAR columns.
-// Otherwise those will be returned with whitespace on the right.
-// assuming "NAME" is defined as CHAR...
-String pgSQL = "SELECT ARTIST_ID, RTRIM(NAME), DATE_OF_BIRTH FROM ARTIST";
-query.setTemplate(PostgresAdapter.class.getName(), pgSQL);</programlisting></para>
-        
-        <section xml:id="sqltemplate-scripting">
-            <title>Scripting SQLTemplate with Velocity</title>
-            <para>The most interesting aspect of SQLTemplate (and the reason why it is called a
-                "template") is that a SQL string is treated by Cayenne as an Apache Velocity
-                template. Before sending it to DB as a PreparedStatement, the String is evaluated in
-                the Velocity context, that does variable substitutions, and performs special
-                callbacks in response to various directives, thus controlling query interaction with
-                the JDBC layer. </para>
-            <para>Check Velocity docs for the syntax details. Here we'll just mention the two main
-                scripting elements - "variables" (that look like <code>$var</code>) and "directives"
-                (that look like <code>#directive(p1 p2 p3)</code>). All built-in Velocity directives
-                are supported. Additionally Cayenne defines a number of its own directives to bind
-                parameters to PreparedStatements and to control the structure of the ResultSet.
-                These directives are described in the following sections.</para>
-        </section>
-        <section xml:id="sqltemplate-parameters">
-            <title>Variable Substitution</title>
-            <para>All variables in the template string are replaced from query
-                parameters:<programlisting language="java">SQLTemplate query = new SQLTemplate(Artist.class, "delete from $tableName");
-query.setParameters(Collections.singletonMap("tableName", "mydb.PAINTING"));
-
-// this will generate SQL like this: "delete from mydb.PAINTING"</programlisting>The
-                example above demonstrates the point made earlier in this chapter - even if we don't
-                know upfront which table the query will run against, we can still use a fixed "root"
-                in constructor (<code>Artist.class</code> in this case) , as we are not planning on
-                converting the result to objects.</para>
-            <para>Variable substitution within the text uses "<code>object.toString()</code>" method to replace the
-                variable value. Keep in mind that this may not be appropriate in all situations.
-                E.g. passing a date object in a WHERE clause expression may be converted to a String
-                not understood by the target RDBMS SQL parser. In such cases variable should be wrapped in <code>#bind</code>
-                directive as described below.</para>
-        </section>
-        <section xml:id="sqltemplate-bind-directive">
-            <title>Directives</title>
-            <para>These are the Cayenne directives used to customize SQLTemplate parsing and
-                integrate it with the JDBC layer: </para>
-            <section>
-                <title>#bind</title>
-                <para>Creates a PreparedStatement positional parameter in place of the directive,
-                    binding the value to it before statement execution. <code>#bind</code> is
-                    allowed in places where a "?" would be allowed in a PreparedStatement. And in
-                    such places it almost always makes sense to pass objects to the template via
-                    this or other forms of <code>#bind</code> instead of inserting them
-                    inline.</para>
-                <para><emphasis role="italic">Semantics:</emphasis></para>
-                <programlisting language="java">#bind(value)
-#bind(value jdbcType)
-#bind(value jdbcType scale)</programlisting>
-                <para><emphasis role="italic">Arguments:</emphasis>
-                    <itemizedlist>
-                        <listitem>
-                            <para><code>value</code> - can either be a char constant or a variable
-                                that is resolved from the query parameters. Note that the variable
-                                can be a collection, that will be automatically expanded into a list
-                                of individual value bindings. This is useful for instance to build
-                                IN conditions. </para>
-                        </listitem>
-                        <listitem>
-                            <para><code>jdbcType</code> - is a JDBC data type of the parameter as
-                                defined in <code>java.sql.Types</code>.</para>
-                        </listitem>
-                        <listitem>
-                            <para><code>scale</code> - An optional scale of the numeric value. Same
-                                as "scale" in PreparedStatement.</para>
-                        </listitem>
-                    </itemizedlist></para>
-                <para>
-                    <emphasis role="italic"
-                    >Usage</emphasis>:<programlisting language="java">#bind($xyz)
-#bind('str')
-#bind($xyz 'VARCHAR')
-#bind($xyz 'DECIMAL' 2)</programlisting></para>
-                <para><emphasis role="italic">Full
-                    example:</emphasis><programlisting language="sql">update ARTIST set NAME = #bind($name) where ID = #bind($id)</programlisting></para>
-            </section>
-            <section>
-                <title>#bindEqual</title>
-                <para>Same as #bind, but also includes the "=" sign in front of the value binding.
-                    Look at the example below - we took the #bind example and replaced "<code>ID =
-                        #bind(..)</code>" with "<code>ID #bindEqual(..)</code>". While it looks like
-                    a clumsy shortcut to eliminate the equal sign, the actual reason why this is
-                    useful is that it allows the value to be null. If the value is not null,
-                        "<code>= ?</code>" is generated, but if it is, the resulting chunk of the
-                    SQL would look like "<code>IS NULL</code>" and will be compilant with what the
-                    DB expects.</para>
-                <para><emphasis role="italic">Semantics:</emphasis></para>
-                <programlisting language="java">#bindEqual(value)
-#bindEqual(value jdbcType)
-#bindEqual(value jdbcType scale)</programlisting>
-                <para><emphasis role="italic">Arguments: (same as #bind)</emphasis>
-                </para>
-                <para>
-                    <emphasis role="italic"
-                    >Usage</emphasis>:<programlisting language="java">#bindEqual($xyz)
-#bindEqual('str')
-#bindEqual($xyz 'VARCHAR')
-#bindEqual($xyz 'DECIMAL' 2)</programlisting></para>
-                <para><emphasis role="italic">Full
-                    example:</emphasis><programlisting language="sql">update ARTIST set NAME = #bind($name) where ID #bindEqual($id)</programlisting></para>
-            </section>
-            <section>
-                <title>#bindNotEqual</title>
-                <para>This directive deals with the same issue as <code>#bindEqual</code> above,
-                    only it generates "not equal" in front of the value (or IS NOT NULL).</para>
-                <para><emphasis role="italic">Semantics:</emphasis></para>
-                <programlisting language="java">#bindNotEqual(value)
-#bindNotEqual(value jdbcType)
-#bindNotEqual(value jdbcType scale)</programlisting>
-                <para><emphasis role="italic">Arguments: (same as #bind)</emphasis></para>
-                <para>
-                    <emphasis role="italic"
-                    >Usage</emphasis>:<programlisting language="java">#bindNotEqual($xyz)
-#bindNotEqual('str')
-#bindNotEqual($xyz 'VARCHAR')
-#bindNotEqual($xyz 'DECIMAL' 2)</programlisting></para>
-                <para><emphasis role="italic">Full
-                    example:</emphasis><programlisting language="sql">update ARTIST set NAME = #bind($name) where ID #bindEqual($id)</programlisting></para>
-            </section>
-            <section>
-                <title>#bindObjectEqual</title>
-                <para>It can be tricky to use a Persistent object or an ObjectId in a binding,
-                    especially for tables with compound primary keys. This directive helps to handle
-                    such binding. It maps columns in the query to the names of Persistent object ID
-                    columns, extracts ID values from the object, and generates SQL like "COL1 = ?
-                    AND COL2 = ? ..." , binding positional parameters to ID values. It can also
-                    correctly handle null object. Also notice how we are specifying a Velocity array
-                    for multi-column PK.</para>
-                <para><emphasis role="italic">Semantics:</emphasis></para>
-                <programlisting language="java">#bindObjectEqual(value columns idColumns)</programlisting>
-                <para><emphasis role="italic">Arguments:</emphasis>
-                    <itemizedlist>
-                        <listitem>
-                            <para><code>value</code> - must be a variable that is resolved from the
-                                query parameters to a Persistent or ObjectId.</para>
-                        </listitem>
-                        <listitem>
-                            <para><code>columns</code> - the names of the columns to generate in the
-                                SQL.</para>
-                        </listitem>
-                        <listitem>
-                            <para><code>idColumn</code> - the names of the ID columns for a given
-                                entity. Must match the order of "columns" to match against.</para>
-                        </listitem>
-                    </itemizedlist></para>
-                <para>
-                    <emphasis role="italic"
-                    >Usage</emphasis>:<programlisting language="java">#bindObjectEqual($a 't0.ID' 'ID')
-#bindObjectEqual($b ['t0.FK1', 't0.FK2'] ['PK1', 'PK2'])</programlisting></para>
-                <para><emphasis role="italic">Full
-                    example:</emphasis><programlisting language="java">String sql = "SELECT * FROM PAINTING t0 WHERE #bindObjectEqual($a 't0.ARTIST_ID' 'ARTIST_ID' ) ORDER BY PAINTING_ID";
-SQLTemplate select = new SQLTemplate(Artist.class, sql);
-
-Artist a = ....
-select.setParameters(Collections.singletonMap("a", a)); </programlisting></para>
-            </section>
-            <section>
-                <title>#bindObjectNotEqual</title>
-                <para>Same as #bindObjectEqual above, only generates "not equal" operator for value
-                    comparison (or IS NOT NULL).</para>
-                <para><emphasis role="italic">Semantics:</emphasis></para>
-                <programlisting language="java">#bindObjectNotEqual(value columns idColumns)</programlisting>
-                <para><emphasis role="italic">Arguments: (same as #bindObjectEqual)</emphasis>
-                </para>
-                <para>
-                    <emphasis role="italic"
-                    >Usage</emphasis>:<programlisting language="java">#bindObjectNotEqual($a 't0.ID' 'ID')
-#bindObjectNotEqual($b ['t0.FK1', 't0.FK2'] ['PK1', 'PK2'])</programlisting></para>
-                <para><emphasis role="italic">Full
-                    example:</emphasis><programlisting language="java">String sql = "SELECT * FROM PAINTING t0 WHERE #bindObjectNotEqual($a 't0.ARTIST_ID' 'ARTIST_ID' ) ORDER BY PAINTING_ID";
-SQLTemplate select = new SQLTemplate(Artist.class, sql);
-
-Artist a = ....
-select.setParameters(Collections.singletonMap("a", a)); </programlisting></para>
-            </section>
-            <section>
-                <title>#result</title>
-                <para>Renders a column in SELECT clause of a query and maps it to a key in the
-                    result DataRow. Also ensures the value read is of the correct type. This allows
-                    to create a DataRow (and ultimately - a persistent object) from an arbitrary
-                    ResultSet.</para>
-                <para><emphasis role="italic">Semantics:</emphasis></para>
-                <programlisting language="java">#result(column)
-#result(column javaType)
-#result(column javaType alias)
-#result(column javaType alias dataRowKey)</programlisting>
-                <para><emphasis role="italic">Arguments:</emphasis>
-                    <itemizedlist>
-                        <listitem>
-                            <para><code>column</code> - the name of the column to render in SQL
-                                SELECT clause.</para>
-                        </listitem>
-                        <listitem>
-                            <para><code>javaType</code> - a fully-qualified Java class name for a
-                                given result column. For simplicity most common Java types used in
-                                JDBC can be specified without a package. These include all numeric
-                                types, primitives, String, SQL dates, BigDecimal and BigInteger. So
-                                    "<code>#result('A' 'String')</code>", "<code>#result('B'
-                                    'java.lang.String')</code>" and "<code>#result('C'
-                                'int')</code>" are all valid</para>
-                        </listitem>
-                        <listitem>
-                            <para><code>alias</code> - specifies both the SQL alias of the column
-                                and the value key in the DataRow. If omitted, "column" value is
-                                used.</para>
-                        </listitem>
-                        <listitem>
-                            <para><code>dataRowKey</code> - needed if SQL 'alias' is not appropriate
-                                as a DataRow key on the Cayenne side. One common case when this
-                                happens is when a DataRow retrieved from a query is mapped using
-                                joint prefetch keys (see below). In this case DataRow must use
-                                database path expressions for joint column keys, and their format is
-                                incompatible with most databases alias format. </para>
-                        </listitem>
-                    </itemizedlist></para>
-                <para>
-                    <emphasis role="italic"
-                    >Usage</emphasis>:<programlisting language="java">#result('NAME')
-#result('DATE_OF_BIRTH' 'java.util.Date') 
-#result('DOB' 'java.util.Date' 'DATE_OF_BIRTH')
-#result('DOB' 'java.util.Date' '' 'artist.DATE_OF_BIRTH') 
-#result('SALARY' 'float') </programlisting></para>
-                <para><emphasis role="italic">Full
-                    example:</emphasis><programlisting language="sql">SELECT #result('ID' 'int'), #result('NAME' 'String'), #result('DATE_OF_BIRTH' 'java.util.Date') FROM ARTIST</programlisting></para>
-            </section>
-            <section>
-                <title>#chain and #chunk</title>
-                
-                    <para><code>#chain</code> and <code>#chunk</code> directives are used for
-                    conditional inclusion of SQL code. They are used together with
-                        <code>#chain</code> wrapping multiple <code>#chunks</code>. A chunk
-                    evaluates its parameter expression and if it is NULL suppresses rendering of the
-                    enclosed SQL block. A chain renders its prefix and its chunks joined by the
-                    operator. If all the chunks are suppressed, the chain itself is suppressed. This
-                    allows to work with otherwise hard to script SQL semantics. E.g. a WHERE clause
-                    can contain multiple conditions joined with AND or OR. Application code would
-                    like to exclude a condition if its right-hand parameter is not present (similar
-                    to Expression pruning discussed above). If all conditions are excluded, the
-                    entire WHERE clause should be excluded. chain/chunk allows to do that.</para>
-                    <para>
-                    <emphasis role="italic"
-                    >Semantics</emphasis>:<programlisting language="java">#chain(operator) ... #end
-#chain(operator prefix) ... #end
-#chunk() ... #end
-#chunk(param) ... #end </programlisting></para>
-                    <para><emphasis role="italic">Full
-                    example:</emphasis><programlisting language="java">#chain('OR' 'WHERE') 
-	#chunk($name) NAME LIKE #bind($name) #end
-	#chunk($id) ARTIST_ID > #bind($id) #end
-#end" </programlisting></para>
-          
-            </section>
-        </section>
-        <section>
-            <title>Mapping SQLTemplate Results</title>
-            <para>Here we'll discuss how to convert the data selected via SQLTemplate to some
-                useable format, compatible with other query results. It can either be very simple or
-                very complex, depending on the structure of the SQL, JDBC driver nature and the
-                desired result structure. This section presents various tips and tricks dealing with
-                result mapping. </para>
-            <para>By default SQLTemplate is expected to return a List of Persistent objects of its
-                root type. This is the simple
-                case:<programlisting language="java">SQLTemplate query = new SQLTemplate(Artist.class, "SELECT * FROM ARTIST");
-
-// List of Artists
-List&lt;Artist> artists = context.performQuery(query);</programlisting>Just
-                like SelectQuery, SQLTemplate can fetch DataRows. In fact DataRows option is very
-                useful with SQLTemplate, as the result type most often than not does not represent a
-                Cayenne entity, but instead may be some aggregated report or any other data whose
-                object structure is opaque to
-                Cayenne:<programlisting language="java">String sql = "SELECT t0.NAME, COUNT(1) FROM ARTIST t0 JOIN PAINTING t1 ON (t0.ID = t1.ARTIST_ID) "
-    + "GROUP BY t0.NAME ORDER BY COUNT(1)";
-SQLTemplate query = new SQLTemplate(Artist.class, sql);
-
-// ensure we are fetching DataRows
-query.setFetchingDataRows(true);
-
-// List of DataRow
-List&lt;DataRow> rows = context.performQuery(query);</programlisting>In
-                the example above, even though the query root is Artist. the result is a list of
-                artist names with painting counts (as mentioned before in such case "root" is only
-                used to find the DB to fetch against, but has no bearning on the result). The
-                DataRows here are the most appropriate and desired result type.</para>
-            <para>In a more advanced case you may decide to fetch a list of scalars or a list of
-                Object[] with each array entry being either an entity or a scalar. You probably
-                won't be doing this too often and it requires quite a lot of work to setup, but if
-                you want your SQLTemplate to return results similar to EJBQLQuery, it is doable
-                using SQLResult as described
-                below:<programlisting language="java">SQLTemplate query = new SQLTemplate(Painting.class, "SELECT ESTIMATED_PRICE P FROM PAINTING");
-
-// let Cayenne know that result is a scalar
-SQLResult resultDescriptor = new SQLResult();
-resultDescriptor.addColumnResult("P");
-query.setResult(resultDescriptor);
-
-// List of BigDecimals
-List&lt;BigDecimal> prices = context.performQuery(query); </programlisting><programlisting language="java">SQLTemplate query = new SQLTemplate(Artist.class, "SELECT t0.ID, t0.NAME, t0.DATE_OF_BIRTH, COUNT(t1.PAINTING_ID) C " +
-      "FROM ARTIST t0 LEFT JOIN PAINTING t1 ON (t0.ID = t1.ARTIST_ID) " +
-      "GROUP BY t0.ID, t0.NAME, t0.DATE_OF_BIRTH");
-
-// let Cayenne know that result is a mix of Artist objects and the count of their paintings
-EntityResult artistResult = new EntityResult(Artist.class);
-artistResult.addDbField(Artist.ID_PK_COLUMN, "ARTIST_ID");
-artistResult.addObjectField(Artist.NAME_PROPERTY, "NAME");
-artistResult.addObjectField(Artist.DATE_OF_BIRTH_PROPERTY, "DATE_OF_BIRTH");
-
-SQLResult resultDescriptor = new SQLResult();
-resultDescriptor.addEntityResult(artistResult);
-resultDescriptor.addColumnResult("C");
-query.setResult(resultDescriptor);
-
-// List of Object[]
-List&lt;Object[]> data = context.performQuery(query);</programlisting></para>
-            <para>Another trick related to mapping result sets is making Cayenne recognize
-                prefetched entities in the result set. This emulates "joint" prefetching of
-                SelectQuery, and is achieved by special column naming. Columns belonging to the
-                "root" entity of the query should use unqualified names corresponding to the root
-                DbEntity columns. For each related entity column names must be prefixed with
-                relationship name and a dot (e.g. "toArtist.ID"). Column naming can be controlled
-                with "#result"
-                directive:<programlisting language="java">String sql = "SELECT distinct "
-    + "#result('t1.ESTIMATED_PRICE' 'BigDecimal' '' 'paintings.ESTIMATED_PRICE'), "
-    + "#result('t1.PAINTING_TITLE' 'String' '' 'paintings.PAINTING_TITLE'), "
-    + "#result('t1.GALLERY_ID' 'int' '' 'paintings.GALLERY_ID'), "
-    + "#result('t1.ID' 'int' '' 'paintings.ID'), "
-    + "#result('NAME' 'String'), "
-    + "#result('DATE_OF_BIRTH' 'java.util.Date'), "
-    + "#result('t0.ID' 'int' '' 'ID') "
-    + "FROM ARTIST t0, PAINTING t1 "
-    + "WHERE t0.ID = t1.ARTIST_ID";
-
-SQLTemplate q = new SQLTemplate(Artist.class, sql);
-q.addPrefetch(Artist.PAINTINGS_PROPERTY)
-List&lt;Artist> objects = context.performQuery(query);</programlisting></para>
-            <para>And the final tip deals with capitalization of the DataRow keys. Queries like
-                    "<code>SELECT * FROM...</code>" and even "<code>SELECT COLUMN1, COLUMN2, ...
-                    FROM ...</code>" can sometimes result in Cayenne exceptions on attempts to
-                convert fetched DataRows to objects. Essentially any query that is not using a
-                    <code>#result</code> directive to describe the result set is prone to this
-                problem, as different databases may produce different capitalization of the
-                java.sql.ResultSet columns. </para>
-            <para>The most universal way to address this issue is to describe each column explicitly
-                in the SQLTemplate via <code>#result</code>, e.g.: "<code>SELECT #result('column1'),
-                    #result('column2'), ..</code>". However this quickly becomes impractical for
-                tables with lots of columns. For such cases Cayenne provides a shortcut based on the
-                fact that an ORM mapping usually follows some naming convention for the column
-                names. Simply put, for case-insensitive databases developers normally use either all
-                lowercase or all uppercase column names. Here is the API that takes advantage of
-                that user knowledge and forces Cayenne to follow a given naming convention for the
-                DataRow keys (this is also available as a dropdown in the
-                Modeler):<programlisting language="java">SQLTemplate query = new SQLTemplate("SELECT * FROM ARTIST");
-query.setColumnNamesCapitalization(CapsStrategy.LOWER);
-List objects = context.performQuery(query);</programlisting></para>
-            <para>or<programlisting language="java">SQLTemplate query = new SQLTemplate("SELECT * FROM ARTIST");
-query.setColumnNamesCapitalization(CapsStrategy.UPPER);
-List objects = context.performQuery(query); </programlisting></para>
-            <para>None of this affects the generated SQL, but the resulting DataRows are using
-                correct capitalization. Note that you probably shouldn't bother with this unless you
-                are getting CayenneRuntimeExceptions when fetching with SQLTemplate.</para>
-        </section>
-    </section>
-    <section xml:id="procedurequery">
-        <title>ProcedureQuery</title>
-        <para>Stored procedures are mapped as separate objects in CayenneModeler. ProcedureQuery
-            provides a way to execute them with a certain set of parameters. Just like with
-            SQLTemplate, the outcome of a procedure can be anything - a single result set, mutliple
-            result sets, some data modification (returned as an update count), or a combination of
-            these. So use "performQuery" to get a single result set, and use "performGenericQuery"
-            for anything
-            else:<programlisting language="java">ProcedureQuery query = new ProcedureQuery("my_procedure", Artist.class);
-
-// Set "IN" parameter values
-query.addParam("p1", "abc");
-query.addParam("p2", 3000);
-
-List&lt;Artist> result = context.performQuery(query);</programlisting><programlisting language="java">// here we do not bother with root class. 
-// Procedure name gives us needed routing information
-ProcedureQuery query = new ProcedureQuery("my_procedure");
-
-query.addParam("p1", "abc");
-query.addParam("p2", 3000);
-
-QueryResponse response = context.performGenericQuery(query); </programlisting></para>
-        <para>A stored procedure can return data back to the application as result sets or via OUT
-            parameters. To simplify the processing of the query output, QueryResponse treats OUT
-            parameters as if it was a separate result set. If a stored procedure declares any OUT or
-            INOUT parameters, QueryResponse will contain their returned values in the very first
-            result
-            list:<programlisting language="java">ProcedureQuery query = new ProcedureQuery("my_procedure");
-QueryResponse response = context.performGenericQuery(query);
-
-// read OUT parameters
-List out = response.firstList();
-
-if(!out.isEmpty()) {
-    Map outParameterValues = (Map) outList.get(0);
-}</programlisting></para>
-        <para>There maybe a situation when a stored procedure handles its own transactions, but an
-            application is configured to use Cayenne-managed transactions. This is obviously
-            conflicting and undesirable behavior. In this case ProcedureQueries should be executed
-            explicitly wrapped in an "external" Transaction. This is one of the few cases when a
-            user should worry about transactions at all. See Transactions section for more
-            details.</para>
-    </section>
-    <section xml:id="namedquery">
-        <title>NamedQuery</title>
-        <para>NamedQuery is a query that is a reference to another query stored in the DataMap. The
-            actual stored query can be SelectQuery, SQLTemplate, EJBQLQuery, etc. It doesn't matter
-            - the API for calling them is the same - via a
-            NamedQuery:<programlisting language="java">String[] keys = new String[] {"loginid", "password"};
-Object[] values = new String[] {"joe", "secret"};
-
-NamedQuery query = new NamedQuery("Login", keys, values);
-
-List&lt;User> matchingUsers = context.performQuery(query); </programlisting></para>
-    </section>
-    <section xml:id="custom-queries">
-        <title>Custom Queries</title>
-        <para>If a user needs some extra functionality not addressed by the existing set of Cayenne
-            queries, he can write his own. The only requirement is to implement
-                <code>org.apache.cayenne.query.Query</code> interface. The easiest way to go about
-            it is to subclass some of the base queries in Cayenne. </para>
-        <para>E.g. to do something directly in the JDBC layer, you might subclass
-            AbstractQuery:<programlisting language="java">public class MyQuery extends AbstractQuery {
-
-    @Override
-    public SQLAction createSQLAction(SQLActionVisitor visitor) {
-        return new SQLAction() {
-
-            @Override
-            public void performAction(Connection connection, OperationObserver observer) throws SQLException, Exception {
-                // 1. do some JDBC work using provided connection... 
-                // 2. push results back to Cayenne via OperationObserver
-            }
-        };
-    }
-}</programlisting></para>
-        <para>To delegate the actual query execution to a standard Cayenne query, you may subclass
-            IndirectQuery:<programlisting language="java">public class MyDelegatingQuery extends IndirectQuery {
-    
-    @Override
-    protected Query createReplacementQuery(EntityResolver resolver) {
-        SQLTemplate delegate = new SQLTemplate(SomeClass.class, generateRawSQL());
-        delegate.setFetchingDataRows(true);
-        return delegate;
-    }
-    
-    protected String generateRawSQL() {
-        // build some SQL string
-    }
-}</programlisting></para>
-        <para>In fact many internal Cayenne queries are IndirectQueries, delegating to SelectQuery
-            or SQLTemplate after some preprocessing.</para>
-    </section>
+    <xi:include href="queries-select.xml"/>
+    <xi:include href="queries-ejbql.xml"/>
+    <xi:include href="queries-selectbyid.xml"/>
+    <xi:include href="queries-sqlselect.xml"/>
+    <xi:include href="queries-mapped.xml"/>
+    <xi:include href="queries-procedurecall.xml"/>
+    <xi:include href="queries-custom.xml"/>
+    <xi:include href="queries-sqltemplate.xml"/>
+
+    <!-- ProcedureQuery is not deprecated as of 4.0 but newer ProcedureCall is preferred -->
+    <!--<xi:include href="queries-procedure.xml"/>-->
+    <!-- NamedQuery deprecated since 4.0 -->
+    <!--<xi:include href="queries-namedquery.xml"/>-->
 </chapter>


[07/10] cayenne git commit: Cleanup

Posted by nt...@apache.org.
Cleanup


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/dbd733ab
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/dbd733ab
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/dbd733ab

Branch: refs/heads/STABLE-4.0
Commit: dbd733abd2365cb7c0af4a5e41d621985e2cf04f
Parents: 5e37020
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Sep 22 17:28:14 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Sep 22 17:28:14 2017 +0300

----------------------------------------------------------------------
 .../src/docbkx/customizing-cayenne-runtime.xml  |  6 +-
 .../src/docbkx/ext-project-compatibility.xml    | 59 ---------------
 .../cayenne-guide/src/docbkx/ext-velocity.xml   | 79 --------------------
 docs/docbook/cayenne-guide/src/docbkx/part5.xml |  6 +-
 .../src/docbkx/queries-sqlselect.xml            |  2 +-
 .../src/docbkx/queries-sqltemplate.xml          | 30 +++++++-
 6 files changed, 34 insertions(+), 148 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/dbd733ab/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml b/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml
index 1ffdb3b..3383e01 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml
@@ -265,6 +265,8 @@ binder.bindList(DefaultDbAdapterFactory.DETECTORS_LIST)
             <para>
                 In order to use your custom data type you should implement <code>ValueObjectType</code> describing it in terms of some type already known to Cayenne
                 (e.g. backed by system or user ExtendedType).
+            </para>
+            <para>
                 Let's assume we want to support some data type called <code>Money</code>:
                 <programlisting language="java"><![CDATA[public class Money {
     private BigDecimal value;
@@ -317,8 +319,8 @@ binder.bindList(DefaultDbAdapterFactory.DETECTORS_LIST)
     .build();]]></programlisting>
             </para>
             <para>More examples of implementation you can find in
-                <!--<link xlink:href="https://github.com/apache/cayenne/tree/master/cayenne-java8">cayenne-java8 module</link> or-->
-                <link xlink:href="https://github.com/apache/cayenne/tree/master/cayenne-joda">cayenne-joda module</link>.</para>
+                <link xlink:href="https://github.com/apache/cayenne/tree/STABLE-4.0/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types">cayenne-java8 module</link>
+            </para>
         </section>
         <section xml:id="extendedtypes">
             <title>Extended Types</title>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dbd733ab/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml
deleted file mode 100644
index d645098..0000000
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  ~   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
-  ~  "License"); 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
-  ~  "AS IS" 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.
-  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
-<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
-         version="5.0" xml:id="ext-project-compatibility">
-    <title>Project compatibility extension</title>
-    <section>
-        <title>Description</title>
-        <para>Since version <emphasis>4.1</emphasis> Cayenne doesn't allow to load project XML files
-            from previous versions as this can lead to unexpected errors in runtime. This module allows to
-            use project files from older versions performing their upgrade on the fly (without modifying files).
-            This can be useful when using Cayenne models from third-party libraries in your app.
-            <note>
-                <para>You should prefer explicit project upgrade via Cayenne Modeler.</para>
-            </note>
-        </para>
-    </section>
-    <section>
-        <title>Including in a project</title>
-        <section>
-            <title>Maven</title>
-            <para>
-                <programlisting language="xml">&lt;dependency>
-    &lt;groupId>org.apache.cayenne&lt;/groupId>
-    &lt;artifactId>cayenne-project-compatibility&lt;/artifactId>
-    &lt;version><?eval ${project.version}?>&lt;/version>
-&lt;/dependency></programlisting>
-            </para>
-        </section>
-        <section>
-            <title>Gradle</title>
-            <para>
-                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-project-compatibility:<?eval ${project.version}?>'</programlisting>
-            </para>
-        </section>
-    </section>
-    <section>
-        <title>Usage</title>
-        <para>
-            This module doesn't require any additional setup.
-        </para>
-    </section>
-</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dbd733ab/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml
deleted file mode 100644
index 4086bdf..0000000
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  ~   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
-  ~  "License"); 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
-  ~  "AS IS" 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.
-  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
-<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
-         version="5.0" xml:id="ext-velocity">
-    <title>Apache Velocity extension</title>
-    <section>
-        <title>Description</title>
-        <para>This module enables usage of full featured Apache Velocity templates in <code>org.apache.cayenne.query.SQLTemplate</code>
-        queries.</para>
-    </section>
-    <section>
-        <title>Including in a project</title>
-        <section>
-            <title>Maven</title>
-            <para>
-                <programlisting language="xml">&lt;dependency>
-    &lt;groupId>org.apache.cayenne&lt;/groupId>
-    &lt;artifactId>cayenne-velocity&lt;/artifactId>
-    &lt;version><?eval ${project.version}?>&lt;/version>
-&lt;/dependency></programlisting>
-            </para>
-        </section>
-        <section>
-            <title>Gradle</title>
-            <para>
-                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-velocity:<?eval ${project.version}?>'</programlisting>
-            </para>
-        </section>
-    </section>
-    <section>
-        <title>Usage</title>
-        <para>
-            This module doesn't require any additional setup.
-        </para>
-        <para>
-            In addition of directives mentioned in <link linkend="sqltemplate-bind-directive">this</link> chapter, this module enables <code>#chain</code> and <code>#chunk</code>
-            directives.
-        </para>
-        <para><code>#chain</code> and <code>#chunk</code> directives are used for
-            conditional inclusion of SQL code. They are used together with
-            <code>#chain</code> wrapping multiple <code>#chunks</code>. A chunk
-            evaluates its parameter expression and if it is NULL suppresses rendering of the
-            enclosed SQL block. A chain renders its prefix and its chunks joined by the
-            operator. If all the chunks are suppressed, the chain itself is suppressed. This
-            allows to work with otherwise hard to script SQL semantics. E.g. a WHERE clause
-            can contain multiple conditions joined with AND or OR. Application code would
-            like to exclude a condition if its right-hand parameter is not present (similar
-            to Expression pruning discussed above). If all conditions are excluded, the
-            entire WHERE clause should be excluded. chain/chunk allows to do that.</para>
-        <para>
-            <emphasis role="italic"
-            >Semantics</emphasis>:<programlisting language="java">#chain(operator) ... #end
-#chain(operator prefix) ... #end
-#chunk() ... #end
-#chunk(param) ... #end </programlisting></para>
-        <para><emphasis role="italic">Full
-            example:</emphasis><programlisting language="java">#chain('OR' 'WHERE')
-    #chunk($name) NAME LIKE #bind($name) #end
-    #chunk($id) ARTIST_ID > #bind($id) #end
-#end" </programlisting></para>
-    </section>
-</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dbd733ab/docs/docbook/cayenne-guide/src/docbkx/part5.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/part5.xml b/docs/docbook/cayenne-guide/src/docbkx/part5.xml
index ee95291..347f6ce 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/part5.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/part5.xml
@@ -23,10 +23,8 @@
     <xi:include href="ext-cache-invalidation.xml"/>
     <xi:include href="ext-commit-log.xml"/>
     <xi:include href="ext-crypto.xml"/>
-    <!--<xi:include href="ext-dbcp2.xml"/>-->
-    <!--<xi:include href="ext-java8.xml"/>-->
+    <xi:include href="ext-dbcp2.xml"/>
+    <xi:include href="ext-java8.xml"/>
     <xi:include href="ext-jcache.xml"/>
     <xi:include href="ext-joda.xml"/>
-    <xi:include href="ext-project-compatibility.xml"/>
-    <xi:include href="ext-velocity.xml"/>
 </part>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dbd733ab/docs/docbook/cayenne-guide/src/docbkx/queries-sqlselect.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-sqlselect.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-sqlselect.xml
index 20be436..e488fab 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/queries-sqlselect.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-sqlselect.xml
@@ -23,7 +23,7 @@
         <code>SQLSelect</code> and <code>SQLExec</code> are essentially a "fluent" versions of older <code>SQLTemplate</code> query.
         <code>SQLSelect</code> can be used (as name suggests) to select custom data in form of entities, separate columns or collection of <code>DataRow</code>.
         <code>SQLExec</code> is designed to just execute any raw SQL code (e.g. updates, deletes, DDLs, etc.)
-        This queries support all directives described in <link linkend="sqltemplate">SQLTemplate</link> section.
+        These queries support all directives described in <link linkend="sqltemplate">SQLTemplate</link> section.
     </para>
     <para>
         Here is example of how to use <code>SQLSelect</code>:

http://git-wip-us.apache.org/repos/asf/cayenne/blob/dbd733ab/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
index bbfa559..6acc744 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
@@ -281,9 +281,33 @@ select.setParameters(Collections.singletonMap("a", a)); </programlisting></para>
 #result('SALARY' 'float') </programlisting></para>
                 <para><emphasis role="italic">Full
                     example:</emphasis><programlisting language="sql">SELECT #result('ID' 'int'), #result('NAME' 'String'), #result('DATE_OF_BIRTH' 'java.util.Date') FROM ARTIST</programlisting></para>
-                <note>
-                    <para>For advanced features you may look at the <link linkend="ext-velocity">Apache Velocity extension</link></para>
-                </note>
+            </section>
+            <section>
+                <title>#chain and #chunk</title>
+
+                <para><code>#chain</code> and <code>#chunk</code> directives are used for
+                    conditional inclusion of SQL code. They are used together with
+                    <code>#chain</code> wrapping multiple <code>#chunks</code>. A chunk
+                    evaluates its parameter expression and if it is NULL suppresses rendering of the
+                    enclosed SQL block. A chain renders its prefix and its chunks joined by the
+                    operator. If all the chunks are suppressed, the chain itself is suppressed. This
+                    allows to work with otherwise hard to script SQL semantics. E.g. a WHERE clause
+                    can contain multiple conditions joined with AND or OR. Application code would
+                    like to exclude a condition if its right-hand parameter is not present (similar
+                    to Expression pruning discussed above). If all conditions are excluded, the
+                    entire WHERE clause should be excluded. chain/chunk allows to do that.</para>
+                <para>
+                    <emphasis role="italic"
+                    >Semantics</emphasis>:<programlisting language="java">#chain(operator) ... #end
+                    #chain(operator prefix) ... #end
+                    #chunk() ... #end
+                    #chunk(param) ... #end </programlisting></para>
+                <para><emphasis role="italic">Full
+                    example:</emphasis><programlisting language="java">#chain('OR' 'WHERE')
+                    #chunk($name) NAME LIKE #bind($name) #end
+                    #chunk($id) ARTIST_ID > #bind($id) #end
+                    #end" </programlisting></para>
+
             </section>
         </section>
         <section>


[03/10] cayenne git commit: Cayenne additional modules documentation

Posted by nt...@apache.org.
Cayenne additional modules documentation

(cherry picked from commit b073b48)


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/562aac45
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/562aac45
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/562aac45

Branch: refs/heads/STABLE-4.0
Commit: 562aac450f55cfa11bfddaf1d14ea7815632a1ac
Parents: de25580
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Sep 1 14:38:26 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Sep 22 17:04:37 2017 +0300

----------------------------------------------------------------------
 .../src/docbkx/ext-cache-invalidation.xml       |  92 +++++++++++++
 .../cayenne-guide/src/docbkx/ext-commit-log.xml |  89 ++++++++++++
 .../cayenne-guide/src/docbkx/ext-crypto.xml     | 134 +++++++++++++++++++
 .../cayenne-guide/src/docbkx/ext-dbcp2.xml      |  59 ++++++++
 .../cayenne-guide/src/docbkx/ext-java8.xml      |  53 ++++++++
 .../cayenne-guide/src/docbkx/ext-jcache.xml     |  61 +++++++++
 .../cayenne-guide/src/docbkx/ext-joda.xml       |  53 ++++++++
 .../src/docbkx/ext-project-compatibility.xml    |  59 ++++++++
 .../cayenne-guide/src/docbkx/ext-velocity.xml   |  79 +++++++++++
 docs/docbook/cayenne-guide/src/docbkx/index.xml |   1 +
 docs/docbook/cayenne-guide/src/docbkx/part5.xml |  32 +++++
 .../src/docbkx/queries-sqltemplate.xml          |  30 +----
 docs/docbook/cayenne-guide/src/docbkx/setup.xml |   5 +
 .../src/images/ext-crypto-obj-entity.png        | Bin 0 -> 18145 bytes
 .../cayenne-guide/src/images/ext-dbcp-setup.png | Bin 0 -> 33026 bytes
 .../upgrade-guide/src/docbkx/new-features.xml   |  57 ++++++--
 16 files changed, 766 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/ext-cache-invalidation.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-cache-invalidation.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-cache-invalidation.xml
new file mode 100644
index 0000000..e597f42
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-cache-invalidation.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+         version="5.0" xml:id="ext-cache-invalidation">
+    <title>Cache invalidation extension</title>
+    <section>
+        <title>Description</title>
+        <para>Cache invalidation module is small extensions that allows easily manage cache invalidation policy.</para>
+    </section>
+    <section>
+        <title>Including in a Project</title>
+        <section>
+            <title>Maven</title>
+            <para>
+                <programlisting language="xml">&lt;dependency>
+    &lt;groupId>org.apache.cayenne&lt;/groupId>
+    &lt;artifactId>cayenne-cache-invalidation&lt;/artifactId>
+    &lt;version><?eval ${project.version}?>&lt;/version>
+&lt;/dependency></programlisting>
+            </para>
+        </section>
+        <section>
+            <title>Gradle</title>
+            <para>
+                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-cache-invalidation:<?eval ${project.version}?>'</programlisting>
+            </para>
+        </section>
+    </section>
+    <section>
+        <title>Usage</title>
+        <para>
+            Module supports autoloading mechanism, so no other actions required to start using it.
+            Just mark you entities with <code>@CacheGroups</code> annotation:
+            <programlisting language="java"><![CDATA[
+@CacheGroups("some-group")
+public class MyEntity extends _MyEntity {
+    // ...
+}]]></programlisting>
+            That's all, now after any modification of <code>MyEntity</code> objects cache group <code>"some-group"</code>
+            will be invalidated automatically.
+            <note>
+                <para>You can read more about cache and cache groups in corresponding <link linkend="caching-and-fresh-data">chapter</link> of this documentation.</para>
+            </note>
+        </para>
+        <para>
+            In case you need some complex logic of cache invalidation you can disable this default behaviour and
+            provide you own logic.
+        </para>
+        <para>
+            To do so you need to implement <code>org.apache.cayenne.cache.invalidation.InvalidationHandler</code> interface and tell Cache Invalidation module to
+            use it.
+            Let's assume we have our implementation class called <code>CustomInvalidationHandler</code> that will simply match
+            all entities with <code>"custom-group"</code> cache group:
+            <programlisting language="java"><![CDATA[
+public class CustomInvalidationHandler implements InvalidationHandler {
+    @Override
+    public InvalidationFunction canHandle(Class<? extends Persistent> type) {
+        return p -> Collections.singleton(new CacheGroupDescriptor("custom-group"));
+    }
+}]]></programlisting>
+            Now we'll set up it's usage by <code>ServerRuntime</code>:
+            <programlisting language="java"><![CDATA[
+ServerRuntime.builder()
+        .addModule(CacheInvalidationModule.extend()
+                // this will disable default handler based on @CacheGroups, and this is optional
+                .noCacheGroupsHandler()
+                .addHandler(CustomInvalidationHandler.class)
+                .module())
+]]></programlisting>
+            <note>
+                <para>You can combine as many invalidation handlers as you need.</para>
+            </note>
+        </para>
+    </section>
+</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/ext-commit-log.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-commit-log.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-commit-log.xml
new file mode 100644
index 0000000..97c38df
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-commit-log.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+         version="5.0" xml:id="ext-commit-log">
+    <title>Commit log extension</title>
+    <section>
+        <title>Description</title>
+        <para>The goal of this module is to capture commit changes and present them to interested parties in an easy-to-process format.</para>
+    </section>
+    <section>
+        <title>Including in a Project</title>
+        <section>
+            <title>Maven</title>
+            <para>
+                <programlisting language="xml">&lt;dependency>
+    &lt;groupId>org.apache.cayenne&lt;/groupId>
+    &lt;artifactId>cayenne-commitlog&lt;/artifactId>
+    &lt;version><?eval ${project.version}?>&lt;/version>
+&lt;/dependency></programlisting>
+            </para>
+        </section>
+        <section>
+            <title>Gradle</title>
+            <para>
+                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-commitlog:<?eval ${project.version}?>'</programlisting>
+            </para>
+        </section>
+    </section>
+    <section>
+        <title>Usage</title>
+        <para>
+            In order to use <code>commitlog</code> module you need to perform three easy steps:
+            <orderedlist>
+                <listitem>
+                    <para>Mark all entities that changes you interested in with <code>@org.apache.cayenne.commitlog.CommitLog</code> annotation</para>
+                    <programlisting language="java"><![CDATA[
+@CommitLog(ignoredProperties = {"somePropertyToSkip"})
+public class MyEntity extends _MyEntity {
+    // ...
+}]]></programlisting>
+                </listitem>
+                <listitem>
+                    <para>
+                        Implement <code>CommitLogListener</code> interface.
+                        <programlisting language="java"><![CDATA[
+public class MyCommitLogListener implements CommitLogListener {
+    @Override
+    public void onPostCommit(ObjectContext originatingContext, ChangeMap changes) {
+        // ChangeMap will contain all information about changes happened in performed commit
+        // this example will simply print IDs of all inserted objects
+        changes.getUniqueChanges().stream()
+            .filter(change -> change.getType() == ObjectChangeType.INSERT)
+            .map(ObjectChange::getPostCommitId)
+            .forEach(id -> System.out.println("Inserted new entity with id: " + id));
+    }
+}]]></programlisting>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Inject your listener into <code>ServerRuntime</code>
+                        <programlisting language="java"><![CDATA[
+ServerRuntime.builder()
+        .addModule(CommitLogModule.extend()
+                .addListener(MyCommitLogListener.class)
+                .module())]]></programlisting>
+                    </para>
+                </listitem>
+            </orderedlist>
+        </para>
+    </section>
+</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/ext-crypto.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-crypto.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-crypto.xml
new file mode 100644
index 0000000..082e640
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-crypto.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+         version="5.0" xml:id="ext-crypto">
+    <title>Crypto extension</title>
+    <section>
+        <title>Description</title>
+        <para>Crypto module allows encrypt and decrypt values stored in DB transparently to your Java app.</para>
+    </section>
+    <section>
+        <title>Including in a Project</title>
+        <section>
+            <title>Maven</title>
+            <para>
+                <programlisting language="xml">&lt;dependency>
+    &lt;groupId>org.apache.cayenne&lt;/groupId>
+    &lt;artifactId>cayenne-crypto&lt;/artifactId>
+    &lt;version><?eval ${project.version}?>&lt;/version>
+&lt;/dependency></programlisting>
+            </para>
+        </section>
+        <section>
+            <title>Gradle</title>
+            <para>
+                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-crypto:<?eval ${project.version}?>'</programlisting>
+            </para>
+        </section>
+    </section>
+    <section>
+        <title>Usage</title>
+        <section>
+            <title>Setup your model and DB</title>
+            <para>
+                To use crypto you must prepare your database structure to allow <code>byte[]</code> storage.
+                Also you should define naming convention to mark encrypted columns and set appropriate SQL type.
+                Default naming strategy that doesn't require additional setup is using <code>"CRYPTO_"</code> prefix on columns
+                that will contain encrypted data.
+                If you need to you can change this default strategy by injecting you own implementation of
+                <code>org.apache.cayenne.crypto.map.ColumnMapper</code> interface.
+                <programlisting language="java"><![CDATA[
+ServerRuntime.builder()
+        .addModule(CryptoModule.extend()
+                .columnMapper(MyColumnMapper.class)
+                .module())]]></programlisting>
+            </para>
+            <para>
+                Currently supported SQL types that can be used to store encrypted data are:
+                <orderedlist>
+                    <listitem>
+                        <para>
+                            Binary types: <code>BINARY, BLOB, VARBINARY, LONGVARBINARY</code>.
+                            This types are preferred.
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>Character types, that will store <code>base64</code> encoded value:
+                            <code>CHAR, NCHAR, CLOB, NCLOB, LONGVARCHAR, LONGNVARCHAR, VARCHAR, NVARCHAR</code></para>
+                    </listitem>
+                </orderedlist>
+                <note>
+                    <para>Not all data types may be supported by your database.</para>
+                </note>
+            </para>
+            <para>
+                Here is example of how your <code>ObjEntity</code> with two encrypted and two unencrypted properties
+                can look like in the Cayenne Modeler:
+            </para>
+            <para><inlinemediaobject>
+                <imageobject>
+                    <imagedata fileref="images/ext-crypto-obj-entity.png" scalefit="1" width="100%"/>
+                </imageobject>
+            </inlinemediaobject></para>
+        </section>
+        <section>
+            <title>Setup keystore</title>
+            <para>
+                To perform encryption you must provide <code>KEYSTORE_URL</code> and <code>KEY_PASSWORD</code> to this module.
+                Currently crypto module supports only Java "jceks" KeyStore.
+                <programlisting language="java"><![CDATA[
+ServerRuntime.builder()
+        .addModule(CryptoModule.extend()
+                .keyStore(this.getClass().getResource("keystore.jcek"), "my-password".toCharArray(), "my-key-alias")
+                .module())]]></programlisting>
+            </para>
+        </section>
+        <section>
+            <title>Additional settings</title>
+            <para>
+                Additionally to <code>ColumnMapper</code> mentioned above you can customize other parts of
+                <code>crypto module</code>.
+                You can enable <code>gzip</code> compression and <code>HMAC</code> usage (this will ensure integrity of data).
+                <programlisting language="java"><![CDATA[
+ServerRuntime.builder()
+        .addModule(CryptoModule.extend()
+                .compress()
+                .useHMAC()
+                .module())]]></programlisting>
+            </para>
+            <para>
+                Another useful extension point is support for custom Java value types. To add support for your
+                data type you need to implement <code>org.apache.cayenne.crypto.transformer.value.BytesConverter</code>
+                interface that will convert required type to and from <code>byte[]</code>.
+                <programlisting language="java"><![CDATA[
+ServerRuntime.builder()
+        .addModule(CryptoModule.extend()
+                .objectToBytesConverter(MyClass.class, new MyClassBytesConverter())
+                .module())]]></programlisting>
+            </para>
+            <note>
+                <para>In addition to Java primitive types (and their object counterparts), <code>crypto module</code>
+                    by default supports encryption only of <code>java.util.Date</code>, <code>java.math.BigInteger</code>
+                    and <code>java.math.BigDecimal</code> types.
+                </para>
+            </note>
+        </section>
+    </section>
+</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/ext-dbcp2.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-dbcp2.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-dbcp2.xml
new file mode 100644
index 0000000..00097a6
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-dbcp2.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+         version="5.0" xml:id="ext-dbcp2">
+    <title>Apache Commons DBCP integration</title>
+    <section>
+        <title>Description</title>
+        <para>
+            This module enables usage of Apache Commons DBCP2 connection pool.
+        </para>
+    </section>
+    <section>
+        <title>Including in a Project</title>
+        <section>
+            <title>Maven</title>
+            <para>
+                <programlisting language="xml">&lt;dependency>
+    &lt;groupId>org.apache.cayenne&lt;/groupId>
+    &lt;artifactId>cayenne-dbcp2&lt;/artifactId>
+    &lt;version><?eval ${project.version}?>&lt;/version>
+&lt;/dependency></programlisting>
+            </para>
+        </section>
+        <section>
+            <title>Gradle</title>
+            <para>
+                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-dbcp2:<?eval ${project.version}?>'</programlisting>
+            </para>
+        </section>
+    </section>
+    <section>
+        <title>Usage</title>
+        <para>
+            To use DBCP2 pool you can just setup it in <code>DataNode</code> settings in Cayenne Modeler:
+        </para>
+        <para><inlinemediaobject>
+            <imageobject>
+                <imagedata fileref="images/ext-dbcp-setup.png" scalefit="1" width="100%"/>
+            </imageobject>
+        </inlinemediaobject></para>
+    </section>
+</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/ext-java8.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-java8.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-java8.xml
new file mode 100644
index 0000000..912de55
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-java8.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+         version="5.0" xml:id="ext-java8">
+    <title>Java 8 extension</title>
+    <section>
+        <title>Description</title>
+        <para>Java 8 module allows to use <code>java.time.LocalTime</code>, <code>java.time.LocalDate</code>
+        and <code>java.time.LocalDateTime</code> types for entity attributes</para>
+    </section>
+    <section>
+        <title>Including in a Project</title>
+        <section>
+            <title>Maven</title>
+            <para>
+                <programlisting language="xml">&lt;dependency>
+    &lt;groupId>org.apache.cayenne&lt;/groupId>
+    &lt;artifactId>cayenne-java8&lt;/artifactId>
+    &lt;version><?eval ${project.version}?>&lt;/version>
+&lt;/dependency></programlisting>
+            </para>
+        </section>
+        <section>
+            <title>Gradle</title>
+            <para>
+                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-java8:<?eval ${project.version}?>'</programlisting>
+            </para>
+        </section>
+    </section>
+    <section>
+        <title>Usage</title>
+        <para>
+            This module doesn't require any additional setup, you can just use new data types in your model.
+        </para>
+    </section>
+</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/ext-jcache.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-jcache.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-jcache.xml
new file mode 100644
index 0000000..4756eae
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-jcache.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+         version="5.0" xml:id="ext-jcache">
+    <title>JCache integration</title>
+    <section>
+        <title>Description</title>
+        <para>This module allows integrate any JCache (JSR 107) compatible caching provider with Cayenne.</para>
+    </section>
+    <section>
+        <title>Including in a Project</title>
+        <section>
+            <title>Maven</title>
+            <para>
+                <programlisting language="xml">&lt;dependency>
+    &lt;groupId>org.apache.cayenne&lt;/groupId>
+    &lt;artifactId>cayenne-jcache&lt;/artifactId>
+    &lt;version><?eval ${project.version}?>&lt;/version>
+&lt;/dependency></programlisting>
+            </para>
+        </section>
+        <section>
+            <title>Gradle</title>
+            <para>
+                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-jcache:<?eval ${project.version}?>'</programlisting>
+            </para>
+        </section>
+    </section>
+    <section>
+        <title>Usage</title>
+        <para>
+            All you need is to include this module and any compatible caching provider (e.g. Ehcache).
+            If required you can provide own implementation of <code>org.apache.cayenne.jcache.JCacheConfigurationFactory</code>
+            to customize cache configuration.
+        </para>
+        <para>
+            For advanced configuration and management please use provider specific options and tools.
+        </para>
+        <note>
+            <para>You can read about using cache in Cayenne in <link linkend="caching-and-fresh-data">this</link> chapter.</para>
+            <para>You may alse be interested in <link linkend="ext-cache-invalidation">cache invalidation</link> extension.</para>
+        </note>
+    </section>
+</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/ext-joda.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-joda.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-joda.xml
new file mode 100644
index 0000000..47fd080
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-joda.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+         version="5.0" xml:id="ext-joda">
+    <title>Joda time extension</title>
+    <section>
+        <title>Description</title>
+        <para>Joda time module allows to use <code>org.joda.time.LocalTime</code>, <code>org.joda.time.LocalDate</code>,
+            <code>org.joda.time.LocalDateTime</code> and <code>org.joda.time.DateTime</code> types for entity attributes</para>
+    </section>
+    <section>
+        <title>Including in a Project</title>
+        <section>
+            <title>Maven</title>
+            <para>
+                <programlisting language="xml">&lt;dependency>
+    &lt;groupId>org.apache.cayenne&lt;/groupId>
+    &lt;artifactId>cayenne-joda&lt;/artifactId>
+    &lt;version><?eval ${project.version}?>&lt;/version>
+&lt;/dependency></programlisting>
+            </para>
+        </section>
+        <section>
+            <title>Gradle</title>
+            <para>
+                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-joda:<?eval ${project.version}?>'</programlisting>
+            </para>
+        </section>
+    </section>
+    <section>
+        <title>Usage</title>
+        <para>
+            This module doesn't require any additional setup, you can just use new data types in your model.
+        </para>
+    </section>
+</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml
new file mode 100644
index 0000000..eb8fb73
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+         version="5.0" xml:id="ext-project-compatibility">
+    <title>Project compatibility extension</title>
+    <section>
+        <title>Description</title>
+        <para>Since version <emphasis>4.1</emphasis> Cayenne doesn't allow to load project XML files
+            from previous versions as this can lead to unexpected errors in runtime. This module allows to
+            use project files from older versions performing their upgrade on the fly.
+            This can be useful when using Caynnne models from third-party libraries in your app.
+            <note>
+                <para>You should prefer explicit project upgrade via Cayenne Modeler.</para>
+            </note>
+        </para>
+    </section>
+    <section>
+        <title>Including in a Project</title>
+        <section>
+            <title>Maven</title>
+            <para>
+                <programlisting language="xml">&lt;dependency>
+    &lt;groupId>org.apache.cayenne&lt;/groupId>
+    &lt;artifactId>cayenne-project-compatibility&lt;/artifactId>
+    &lt;version><?eval ${project.version}?>&lt;/version>
+&lt;/dependency></programlisting>
+            </para>
+        </section>
+        <section>
+            <title>Gradle</title>
+            <para>
+                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-project-compatibility:<?eval ${project.version}?>'</programlisting>
+            </para>
+        </section>
+    </section>
+    <section>
+        <title>Usage</title>
+        <para>
+            This module doesn't require any additional setup.
+        </para>
+    </section>
+</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml
new file mode 100644
index 0000000..5ddfc98
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+         version="5.0" xml:id="ext-velocity">
+    <title>Apache Velocity extension</title>
+    <section>
+        <title>Description</title>
+        <para>This module enables usage of full featured Apache Velocity templates in <code>org.apache.cayenne.query.SQLTemplate</code>
+        queries.</para>
+    </section>
+    <section>
+        <title>Including in a Project</title>
+        <section>
+            <title>Maven</title>
+            <para>
+                <programlisting language="xml">&lt;dependency>
+    &lt;groupId>org.apache.cayenne&lt;/groupId>
+    &lt;artifactId>cayenne-velocity&lt;/artifactId>
+    &lt;version><?eval ${project.version}?>&lt;/version>
+&lt;/dependency></programlisting>
+            </para>
+        </section>
+        <section>
+            <title>Gradle</title>
+            <para>
+                <programlisting language="groovy">compile 'org.apache.cayenne:cayenne-velocity:<?eval ${project.version}?>'</programlisting>
+            </para>
+        </section>
+    </section>
+    <section>
+        <title>Usage</title>
+        <para>
+            This module doesn't require any additional setup.
+        </para>
+        <para>
+            In addition of directives mentioned in <link linkend="sqltemplate-bind-directive">this</link> chapter, this module enables <code>#chain</code> and <code>#chunk</code>
+            directives.
+        </para>
+        <para><code>#chain</code> and <code>#chunk</code> directives are used for
+            conditional inclusion of SQL code. They are used together with
+            <code>#chain</code> wrapping multiple <code>#chunks</code>. A chunk
+            evaluates its parameter expression and if it is NULL suppresses rendering of the
+            enclosed SQL block. A chain renders its prefix and its chunks joined by the
+            operator. If all the chunks are suppressed, the chain itself is suppressed. This
+            allows to work with otherwise hard to script SQL semantics. E.g. a WHERE clause
+            can contain multiple conditions joined with AND or OR. Application code would
+            like to exclude a condition if its right-hand parameter is not present (similar
+            to Expression pruning discussed above). If all conditions are excluded, the
+            entire WHERE clause should be excluded. chain/chunk allows to do that.</para>
+        <para>
+            <emphasis role="italic"
+            >Semantics</emphasis>:<programlisting language="java">#chain(operator) ... #end
+#chain(operator prefix) ... #end
+#chunk() ... #end
+#chunk(param) ... #end </programlisting></para>
+        <para><emphasis role="italic">Full
+            example:</emphasis><programlisting language="java">#chain('OR' 'WHERE')
+    #chunk($name) NAME LIKE #bind($name) #end
+    #chunk($id) ARTIST_ID > #bind($id) #end
+#end" </programlisting></para>
+    </section>
+</chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/index.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/index.xml b/docs/docbook/cayenne-guide/src/docbkx/index.xml
index b3dc9f2..8ac6c61 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/index.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/index.xml
@@ -42,6 +42,7 @@
     <xi:include href="part2.xml"/>
     <xi:include href="part3.xml"/>
     <xi:include href="part4.xml"/>
+    <xi:include href="part5.xml"/>
     <xi:include href="appendix-a.xml"/>
     <xi:include href="appendix-b.xml"/>
     <xi:include href="appendix-c.xml"/>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/part5.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/part5.xml b/docs/docbook/cayenne-guide/src/docbkx/part5.xml
new file mode 100644
index 0000000..67919f9
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/part5.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<part xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
+      xml:id="cayenne-guide-part5" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <title>Cayenne Additional Modules</title>
+    <xi:include href="ext-cache-invalidation.xml"/>
+    <xi:include href="ext-commit-log.xml"/>
+    <xi:include href="ext-crypto.xml"/>
+    <xi:include href="ext-dbcp2.xml"/>
+    <xi:include href="ext-java8.xml"/>
+    <xi:include href="ext-jcache.xml"/>
+    <xi:include href="ext-joda.xml"/>
+    <xi:include href="ext-project-compatibility.xml"/>
+    <xi:include href="ext-velocity.xml"/>
+</part>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
index 4d0b21c..bbfa559 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
@@ -281,33 +281,9 @@ select.setParameters(Collections.singletonMap("a", a)); </programlisting></para>
 #result('SALARY' 'float') </programlisting></para>
                 <para><emphasis role="italic">Full
                     example:</emphasis><programlisting language="sql">SELECT #result('ID' 'int'), #result('NAME' 'String'), #result('DATE_OF_BIRTH' 'java.util.Date') FROM ARTIST</programlisting></para>
-            </section>
-            <section>
-                <title>#chain and #chunk</title>
-
-                    <para><code>#chain</code> and <code>#chunk</code> directives are used for
-                    conditional inclusion of SQL code. They are used together with
-                        <code>#chain</code> wrapping multiple <code>#chunks</code>. A chunk
-                    evaluates its parameter expression and if it is NULL suppresses rendering of the
-                    enclosed SQL block. A chain renders its prefix and its chunks joined by the
-                    operator. If all the chunks are suppressed, the chain itself is suppressed. This
-                    allows to work with otherwise hard to script SQL semantics. E.g. a WHERE clause
-                    can contain multiple conditions joined with AND or OR. Application code would
-                    like to exclude a condition if its right-hand parameter is not present (similar
-                    to Expression pruning discussed above). If all conditions are excluded, the
-                    entire WHERE clause should be excluded. chain/chunk allows to do that.</para>
-                    <para>
-                    <emphasis role="italic"
-                    >Semantics</emphasis>:<programlisting language="java">#chain(operator) ... #end
-#chain(operator prefix) ... #end
-#chunk() ... #end
-#chunk(param) ... #end </programlisting></para>
-                    <para><emphasis role="italic">Full
-                    example:</emphasis><programlisting language="java">#chain('OR' 'WHERE')
-	#chunk($name) NAME LIKE #bind($name) #end
-	#chunk($id) ARTIST_ID > #bind($id) #end
-#end" </programlisting></para>
-
+                <note>
+                    <para>For advanced features you may look at the <link linkend="ext-velocity">Apache Velocity extension</link></para>
+                </note>
             </section>
         </section>
         <section>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/docbkx/setup.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/setup.xml b/docs/docbook/cayenne-guide/src/docbkx/setup.xml
index 023004e..ba804a6 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/setup.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/setup.xml
@@ -38,6 +38,11 @@
                                     <th>Status</th>
                                 </tr>
                                 <tr>
+                                    <td>4.1</td>
+                                    <td>Java 1.8 or newer</td>
+                                    <td>Development</td>
+                                </tr>
+                                <tr>
                                     <td>4.0</td>
                                     <td>Java 1.7 or newer</td>
                                     <td>Beta</td>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/images/ext-crypto-obj-entity.png
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/images/ext-crypto-obj-entity.png b/docs/docbook/cayenne-guide/src/images/ext-crypto-obj-entity.png
new file mode 100644
index 0000000..2d8c32a
Binary files /dev/null and b/docs/docbook/cayenne-guide/src/images/ext-crypto-obj-entity.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/cayenne-guide/src/images/ext-dbcp-setup.png
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/images/ext-dbcp-setup.png b/docs/docbook/cayenne-guide/src/images/ext-dbcp-setup.png
new file mode 100644
index 0000000..f681b9d
Binary files /dev/null and b/docs/docbook/cayenne-guide/src/images/ext-dbcp-setup.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/562aac45/docs/docbook/upgrade-guide/src/docbkx/new-features.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/upgrade-guide/src/docbkx/new-features.xml b/docs/docbook/upgrade-guide/src/docbkx/new-features.xml
index 1ae6b9a..6481ae3 100644
--- a/docs/docbook/upgrade-guide/src/docbkx/new-features.xml
+++ b/docs/docbook/upgrade-guide/src/docbkx/new-features.xml
@@ -33,7 +33,7 @@
 			<para>Cayenne 3.1 introduced dependency injection and ServerRuntime. 4.0 provides a very convenient utility to create a custom runtime
 				with various extensions. This reduces the code needed to integrate Cayenne in your environment to just a few lines and no
 				boilerplate.
-				E.g.:<programlisting language="java">ServerRuntime runtime = new ServerRuntimeBuilder("myproject")
+				E.g.:<programlisting language="java">ServerRuntime runtime = ServerRuntime.builder("myproject")
         .addConfigs("cayenne-project1.xml", "cayenne-project2.xml")
         .addModule(binder -> binder.bind(JdbcEventLogger.class).toInstance(myLogger))
         .dataSource(myDataSource)
@@ -50,7 +50,8 @@
 				decorators. True to the "smallest-footprint" DI philosophy, decorator approach is
 				very simple and does not require proxies or class enhancement. Just implement the
 				decorated interface and provide a constructor that takes a delegate instance being
-				decorated:<programlisting language="java">public class MyInterfaceDecorator implements MyInterface {
+				decorated:
+				<programlisting language="java">public class MyInterfaceDecorator implements MyInterface {
 
     private MyInterface delegate;
 
@@ -64,13 +65,9 @@
     }
 }
 
-Module module = new Module() {
-
-    @Override
-    public void configure(Binder binder) {
-        binder.decorate(MyInterface.class).before(MyInterfaceDecorator.class);
-    }
-};</programlisting></para>
+Module module = binder ->
+        binder.decorate(MyInterface.class).before(MyInterfaceDecorator.class);</programlisting>
+			</para>
 		</section>
 	</section>
 	<section xml:id="framework-api">
@@ -88,6 +85,17 @@ Module module = new Module() {
      .selectOne(context);</programlisting></para>
 			</section>
 			<section>
+				<title>ColumnSelect</title>
+				<para>
+					This query allows you directly access individual properties of Objects and use functions (including aggregate)
+					via type-safe API.
+					<programlisting language="java"><![CDATA[List<String> names = ObjectSelect
+	.columnQuery(Artist.class, Artist.ARTIST_NAME)
+	.where(Artist.ARTIST_NAME.length().gt(6))
+	.select(context);]]></programlisting>
+				</para>
+			</section>
+			<section>
 				<title>SQLSelect</title>
 				<para>A "chainable" analog of SQLTemplate used specifically to run selecting raw
 					SQL:<programlisting language="java">List&lt;Long> ids = SQLSelect
@@ -161,10 +169,10 @@ Expression e = ExpressionFactory.exp(
 				regular DB storage. Encrypted values can be stored in (VAR)BINARY and (VAR)CHAR columns. Currently "cayenne-crypto" supports
 				AES/CBC/PKCS5Padding encryption (though other cyphers can be added). It also supports encrypted data compression. Here is an example
 				of building a crypto DI module that can be added to
-				ServerRuntime:<programlisting language="java">Module cryptoExtensions = new CryptoModuleBuilder()
+				ServerRuntime:<programlisting language="java">Module cryptoExtensions = CryptoModule.extend()
 	.keyStore("file:///mykeystore", "keystorepassword".toCharArray(), "keyalias")
 	.compress()
-	.build();</programlisting></para>
+	.module();</programlisting></para>
 		</section>
 	</section>
 	<section xml:id="cayenne-modeler">
@@ -179,6 +187,7 @@ Expression e = ExpressionFactory.exp(
 			<para>Managing listeners in the DataMap XML model is counterproductive and confusing, so support for listeners was removed from both
 				the XML and the Modeler. If you previously had listeners mapped in the model, annotate their callback methods, and perform listener
 				registration in the code: <programlisting language="java">runtime.getDataDomain().addListener(myListener);</programlisting>
+				or via DI: <programlisting language="java"><![CDATA[Module module = binder -> ServerModule.contributeDomainListeners(myListener);]]></programlisting>
 				Entity callbacks on the other hand are managed in the Modeler as before.</para>
 		</section>
 	</section>
@@ -199,5 +208,31 @@ Expression e = ExpressionFactory.exp(
 			<para>As was mentioned above, cgen now includes Property&lt;T> static variables for expression building. It is also made smarter about
 				its defaults for "destDir" and "superPkg".</para>
 		</section>
+		<section>
+			<title>Gradle Plugin</title>
+			<para>
+				Cayenne now provides it's own Gradle Plugin that allows you easily integrate <code>cdbimport</code>
+				and <code>cgen</code> tools into your build process.
+				Here is example of it's usage:
+				<programlisting language="groovy">
+buildscript {
+    repositories {
+        mavenCentral()
+    }
+    dependencies {
+        classpath group: 'org.apache.cayenne.plugins', name: 'cayenne-gradle-plugin', version: '<?eval ${project.version}?>'
+    }
+}
+
+apply plugin: 'org.apache.cayenne'
+
+cayenne.defaultDataMap 'datamap.map.xml'
+
+dependencies {
+    compile cayenne.dependency('server')
+    compile cayenne.dependency('java8')
+}</programlisting>
+			</para>
+		</section>
 	</section>
 </article>


[10/10] cayenne git commit: Cleanup

Posted by nt...@apache.org.
Cleanup


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/d5a181ff
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/d5a181ff
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/d5a181ff

Branch: refs/heads/STABLE-4.0
Commit: d5a181fff8a8a0416f642de525bcaaa7473508b8
Parents: cf303c4
Author: Nikita Timofeev <st...@gmail.com>
Authored: Tue Sep 26 11:19:56 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Tue Sep 26 11:19:56 2017 +0300

----------------------------------------------------------------------
 docs/docbook/cayenne-guide/src/docbkx/queries-select.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/d5a181ff/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
index 035fdb2..3e00d85 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
@@ -79,7 +79,7 @@ INFO: === returned 1 row. - took 6 ms.</screen>
         </para>
     </section>
     <section>
-        <title>Selecting using aggregate functions</title>
+        <title>Selecting aggregate functions</title>
         <para>
             ObjectSelect query supports usage of aggregate functions.
             Most common variant of aggregation is selecting count of records, this can be done really easy:


[04/10] cayenne git commit: Documentation cleanup

Posted by nt...@apache.org.
Documentation cleanup

(cherry picked from commit a407572)


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/afb731f7
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/afb731f7
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/afb731f7

Branch: refs/heads/STABLE-4.0
Commit: afb731f77f7022403d1700767955e5666468f60a
Parents: 562aac4
Author: Nikita Timofeev <st...@gmail.com>
Authored: Thu Sep 21 14:31:59 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Sep 22 17:04:52 2017 +0300

----------------------------------------------------------------------
 .../src/docbkx/ext-cache-invalidation.xml       | 21 ++++++-----
 .../cayenne-guide/src/docbkx/ext-commit-log.xml | 10 +++---
 .../cayenne-guide/src/docbkx/ext-crypto.xml     | 37 ++++++++++----------
 .../cayenne-guide/src/docbkx/ext-dbcp2.xml      |  4 +--
 .../cayenne-guide/src/docbkx/ext-java8.xml      |  2 +-
 .../cayenne-guide/src/docbkx/ext-jcache.xml     | 12 +++----
 .../cayenne-guide/src/docbkx/ext-joda.xml       |  2 +-
 .../src/docbkx/ext-project-compatibility.xml    |  6 ++--
 .../cayenne-guide/src/docbkx/ext-velocity.xml   |  2 +-
 docs/docbook/cayenne-guide/src/docbkx/part5.xml |  4 +--
 .../cayenne-guide/src/docbkx/queries-mapped.xml |  2 +-
 11 files changed, 51 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/ext-cache-invalidation.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-cache-invalidation.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-cache-invalidation.xml
index e597f42..f3e0a0d 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-cache-invalidation.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-cache-invalidation.xml
@@ -22,10 +22,10 @@
     <title>Cache invalidation extension</title>
     <section>
         <title>Description</title>
-        <para>Cache invalidation module is small extensions that allows easily manage cache invalidation policy.</para>
+        <para>Cache invalidation module is an extension that allows to define cache invalidation policy programmatically.</para>
     </section>
     <section>
-        <title>Including in a Project</title>
+        <title>Including in a project</title>
         <section>
             <title>Maven</title>
             <para>
@@ -46,28 +46,27 @@
     <section>
         <title>Usage</title>
         <para>
-            Module supports autoloading mechanism, so no other actions required to start using it.
-            Just mark you entities with <code>@CacheGroups</code> annotation:
+            Module supports autoloading mechanism, so no other actions required to enable it.
+            Just mark your entities with <code>@CacheGroups</code> annotation and you are ready to use it:
             <programlisting language="java"><![CDATA[
 @CacheGroups("some-group")
 public class MyEntity extends _MyEntity {
     // ...
 }]]></programlisting>
-            That's all, now after any modification of <code>MyEntity</code> objects cache group <code>"some-group"</code>
-            will be invalidated automatically.
+            After any modification of <code>MyEntity</code> objects cache group <code>"some-group"</code>
+            will be dropped from cache automatically.
             <note>
                 <para>You can read more about cache and cache groups in corresponding <link linkend="caching-and-fresh-data">chapter</link> of this documentation.</para>
             </note>
         </para>
         <para>
-            In case you need some complex logic of cache invalidation you can disable this default behaviour and
-            provide you own logic.
+            In case you need some complex logic of cache invalidation you can disable default behaviour and provide your own.
         </para>
         <para>
-            To do so you need to implement <code>org.apache.cayenne.cache.invalidation.InvalidationHandler</code> interface and tell Cache Invalidation module to
+            To do so you need to implement <code>org.apache.cayenne.cache.invalidation.InvalidationHandler</code> interface and setup Cache Invalidation module to
             use it.
-            Let's assume we have our implementation class called <code>CustomInvalidationHandler</code> that will simply match
-            all entities with <code>"custom-group"</code> cache group:
+            Let's use implementation class called <code>CustomInvalidationHandler</code> that will simply match
+            all entities' types with <code>"custom-group"</code> cache group regardless of any annotations:
             <programlisting language="java"><![CDATA[
 public class CustomInvalidationHandler implements InvalidationHandler {
     @Override

http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/ext-commit-log.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-commit-log.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-commit-log.xml
index 97c38df..20aec52 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-commit-log.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-commit-log.xml
@@ -25,7 +25,7 @@
         <para>The goal of this module is to capture commit changes and present them to interested parties in an easy-to-process format.</para>
     </section>
     <section>
-        <title>Including in a Project</title>
+        <title>Including in a project</title>
         <section>
             <title>Maven</title>
             <para>
@@ -46,12 +46,12 @@
     <section>
         <title>Usage</title>
         <para>
-            In order to use <code>commitlog</code> module you need to perform three easy steps:
+            In order to use <code>commitlog</code> module you need to perform three steps:
             <orderedlist>
                 <listitem>
-                    <para>Mark all entities that changes you interested in with <code>@org.apache.cayenne.commitlog.CommitLog</code> annotation</para>
+                    <para>Mark all entities which changes you are interested in with <code>@org.apache.cayenne.commitlog.CommitLog</code> annotation</para>
                     <programlisting language="java"><![CDATA[
-@CommitLog(ignoredProperties = {"somePropertyToSkip"})
+@CommitLog(ignoredProperties = {"somePrivatePropertyToSkip"})
 public class MyEntity extends _MyEntity {
     // ...
 }]]></programlisting>
@@ -64,7 +64,7 @@ public class MyCommitLogListener implements CommitLogListener {
     @Override
     public void onPostCommit(ObjectContext originatingContext, ChangeMap changes) {
         // ChangeMap will contain all information about changes happened in performed commit
-        // this example will simply print IDs of all inserted objects
+        // this particular example will print IDs of all inserted objects
         changes.getUniqueChanges().stream()
             .filter(change -> change.getType() == ObjectChangeType.INSERT)
             .map(ObjectChange::getPostCommitId)

http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/ext-crypto.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-crypto.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-crypto.xml
index 082e640..8381bab 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-crypto.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-crypto.xml
@@ -25,7 +25,7 @@
         <para>Crypto module allows encrypt and decrypt values stored in DB transparently to your Java app.</para>
     </section>
     <section>
-        <title>Including in a Project</title>
+        <title>Including in a project</title>
         <section>
             <title>Maven</title>
             <para>
@@ -48,17 +48,8 @@
         <section>
             <title>Setup your model and DB</title>
             <para>
-                To use crypto you must prepare your database structure to allow <code>byte[]</code> storage.
-                Also you should define naming convention to mark encrypted columns and set appropriate SQL type.
-                Default naming strategy that doesn't require additional setup is using <code>"CRYPTO_"</code> prefix on columns
-                that will contain encrypted data.
-                If you need to you can change this default strategy by injecting you own implementation of
-                <code>org.apache.cayenne.crypto.map.ColumnMapper</code> interface.
-                <programlisting language="java"><![CDATA[
-ServerRuntime.builder()
-        .addModule(CryptoModule.extend()
-                .columnMapper(MyColumnMapper.class)
-                .module())]]></programlisting>
+                To use crypto module you must prepare your database to allow <code>byte[]</code> storage and properly name
+                columns that will contain encrypted values.
             </para>
             <para>
                 Currently supported SQL types that can be used to store encrypted data are:
@@ -66,7 +57,7 @@ ServerRuntime.builder()
                     <listitem>
                         <para>
                             Binary types: <code>BINARY, BLOB, VARBINARY, LONGVARBINARY</code>.
-                            This types are preferred.
+                            These types are preferred.
                         </para>
                     </listitem>
                     <listitem>
@@ -79,8 +70,18 @@ ServerRuntime.builder()
                 </note>
             </para>
             <para>
-                Here is example of how your <code>ObjEntity</code> with two encrypted and two unencrypted properties
-                can look like in the Cayenne Modeler:
+                Default naming strategy that doesn't require additional setup suggests using <code>"CRYPTO_"</code> prefix.
+                You can change this default strategy by injecting you own implementation of
+                <code>org.apache.cayenne.crypto.map.ColumnMapper</code> interface.
+                <programlisting language="java"><![CDATA[
+ServerRuntime.builder()
+        .addModule(CryptoModule.extend()
+                .columnMapper(MyColumnMapper.class)
+                .module())]]></programlisting>
+            </para>
+            <para>
+                Here is an example of how <code>ObjEntity</code> with two encrypted and two unencrypted properties
+                can look like:
             </para>
             <para><inlinemediaobject>
                 <imageobject>
@@ -91,7 +92,7 @@ ServerRuntime.builder()
         <section>
             <title>Setup keystore</title>
             <para>
-                To perform encryption you must provide <code>KEYSTORE_URL</code> and <code>KEY_PASSWORD</code> to this module.
+                To perform encryption you must provide <code>KEYSTORE_URL</code> and <code>KEY_PASSWORD</code>.
                 Currently crypto module supports only Java "jceks" KeyStore.
                 <programlisting language="java"><![CDATA[
 ServerRuntime.builder()
@@ -105,7 +106,7 @@ ServerRuntime.builder()
             <para>
                 Additionally to <code>ColumnMapper</code> mentioned above you can customize other parts of
                 <code>crypto module</code>.
-                You can enable <code>gzip</code> compression and <code>HMAC</code> usage (this will ensure integrity of data).
+                You can enable <code>gzip</code> compression and <code>HMAC</code> usage (later will ensure integrity of data).
                 <programlisting language="java"><![CDATA[
 ServerRuntime.builder()
         .addModule(CryptoModule.extend()
@@ -125,7 +126,7 @@ ServerRuntime.builder()
             </para>
             <note>
                 <para>In addition to Java primitive types (and their object counterparts), <code>crypto module</code>
-                    by default supports encryption only of <code>java.util.Date</code>, <code>java.math.BigInteger</code>
+                    supports encryption only of <code>java.util.Date</code>, <code>java.math.BigInteger</code>
                     and <code>java.math.BigDecimal</code> types.
                 </para>
             </note>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/ext-dbcp2.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-dbcp2.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-dbcp2.xml
index 00097a6..715ebc6 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-dbcp2.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-dbcp2.xml
@@ -27,7 +27,7 @@
         </para>
     </section>
     <section>
-        <title>Including in a Project</title>
+        <title>Including in a project</title>
         <section>
             <title>Maven</title>
             <para>
@@ -48,7 +48,7 @@
     <section>
         <title>Usage</title>
         <para>
-            To use DBCP2 pool you can just setup it in <code>DataNode</code> settings in Cayenne Modeler:
+            To use DBCP2 pool you need to setup it in <code>DataNode</code> settings in Cayenne Modeler:
         </para>
         <para><inlinemediaobject>
             <imageobject>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/ext-java8.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-java8.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-java8.xml
index 912de55..9ee1e70 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-java8.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-java8.xml
@@ -26,7 +26,7 @@
         and <code>java.time.LocalDateTime</code> types for entity attributes</para>
     </section>
     <section>
-        <title>Including in a Project</title>
+        <title>Including in a project</title>
         <section>
             <title>Maven</title>
             <para>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/ext-jcache.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-jcache.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-jcache.xml
index 4756eae..509d538 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-jcache.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-jcache.xml
@@ -22,10 +22,10 @@
     <title>JCache integration</title>
     <section>
         <title>Description</title>
-        <para>This module allows integrate any JCache (JSR 107) compatible caching provider with Cayenne.</para>
+        <para>This module allows to integrate any JCache (JSR 107) compatible caching provider with Cayenne.</para>
     </section>
     <section>
-        <title>Including in a Project</title>
+        <title>Including in a project</title>
         <section>
             <title>Maven</title>
             <para>
@@ -46,16 +46,16 @@
     <section>
         <title>Usage</title>
         <para>
-            All you need is to include this module and any compatible caching provider (e.g. Ehcache).
-            If required you can provide own implementation of <code>org.apache.cayenne.jcache.JCacheConfigurationFactory</code>
-            to customize cache configuration.
+            To use JCache provider in your app you need to include this module and caching provider libs (e.g. Ehcache).
+            You can provide own implementation of <code>org.apache.cayenne.jcache.JCacheConfigurationFactory</code>
+            to customize cache configuration if required.
         </para>
         <para>
             For advanced configuration and management please use provider specific options and tools.
         </para>
         <note>
             <para>You can read about using cache in Cayenne in <link linkend="caching-and-fresh-data">this</link> chapter.</para>
-            <para>You may alse be interested in <link linkend="ext-cache-invalidation">cache invalidation</link> extension.</para>
+            <para>You may else be interested in <link linkend="ext-cache-invalidation">cache invalidation</link> extension.</para>
         </note>
     </section>
 </chapter>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/ext-joda.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-joda.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-joda.xml
index 47fd080..d777b68 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-joda.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-joda.xml
@@ -26,7 +26,7 @@
             <code>org.joda.time.LocalDateTime</code> and <code>org.joda.time.DateTime</code> types for entity attributes</para>
     </section>
     <section>
-        <title>Including in a Project</title>
+        <title>Including in a project</title>
         <section>
             <title>Maven</title>
             <para>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml
index eb8fb73..d645098 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-project-compatibility.xml
@@ -24,15 +24,15 @@
         <title>Description</title>
         <para>Since version <emphasis>4.1</emphasis> Cayenne doesn't allow to load project XML files
             from previous versions as this can lead to unexpected errors in runtime. This module allows to
-            use project files from older versions performing their upgrade on the fly.
-            This can be useful when using Caynnne models from third-party libraries in your app.
+            use project files from older versions performing their upgrade on the fly (without modifying files).
+            This can be useful when using Cayenne models from third-party libraries in your app.
             <note>
                 <para>You should prefer explicit project upgrade via Cayenne Modeler.</para>
             </note>
         </para>
     </section>
     <section>
-        <title>Including in a Project</title>
+        <title>Including in a project</title>
         <section>
             <title>Maven</title>
             <para>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml b/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml
index 5ddfc98..4086bdf 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/ext-velocity.xml
@@ -26,7 +26,7 @@
         queries.</para>
     </section>
     <section>
-        <title>Including in a Project</title>
+        <title>Including in a project</title>
         <section>
             <title>Maven</title>
             <para>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/part5.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/part5.xml b/docs/docbook/cayenne-guide/src/docbkx/part5.xml
index 67919f9..ee95291 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/part5.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/part5.xml
@@ -23,8 +23,8 @@
     <xi:include href="ext-cache-invalidation.xml"/>
     <xi:include href="ext-commit-log.xml"/>
     <xi:include href="ext-crypto.xml"/>
-    <xi:include href="ext-dbcp2.xml"/>
-    <xi:include href="ext-java8.xml"/>
+    <!--<xi:include href="ext-dbcp2.xml"/>-->
+    <!--<xi:include href="ext-java8.xml"/>-->
     <xi:include href="ext-jcache.xml"/>
     <xi:include href="ext-joda.xml"/>
     <xi:include href="ext-project-compatibility.xml"/>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/afb731f7/docs/docbook/cayenne-guide/src/docbkx/queries-mapped.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-mapped.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-mapped.xml
index b80e828..c3d7dd1 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/queries-mapped.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-mapped.xml
@@ -25,7 +25,7 @@
         Difference between <code>MappedSelect</code> and <code>MappedExec</code> is (as reflected in their names)
         whether underlying query intended to select data or just to perform some generic SQL code.
         <note>
-            <para>This queries are "fluent" versions of deprecated <code>NamedQuery</code> class.</para>
+            <para>These queries are "fluent" versions of deprecated <code>NamedQuery</code> class.</para>
         </note>
     </para>
     <para>


[09/10] cayenne git commit: Merge branch '4.0-docs-backport' into asf-STABLE-4.0

Posted by nt...@apache.org.
Merge branch '4.0-docs-backport' into asf-STABLE-4.0


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/cf303c44
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/cf303c44
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/cf303c44

Branch: refs/heads/STABLE-4.0
Commit: cf303c442b482dea34570b6d4d8792157cfce3ba
Parents: 25f3ba0 8df7c5d
Author: Nikita Timofeev <st...@gmail.com>
Authored: Mon Sep 25 18:01:28 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Mon Sep 25 18:01:28 2017 +0300

----------------------------------------------------------------------
 docs/doc/src/main/resources/UPGRADE.txt         |   2 +-
 .../src/docbkx/customizing-cayenne-runtime.xml  | 154 +++--
 .../src/docbkx/ext-cache-invalidation.xml       |  91 +++
 .../cayenne-guide/src/docbkx/ext-commit-log.xml |  89 +++
 .../cayenne-guide/src/docbkx/ext-crypto.xml     | 135 ++++
 .../cayenne-guide/src/docbkx/ext-dbcp2.xml      |  59 ++
 .../cayenne-guide/src/docbkx/ext-java8.xml      |  53 ++
 .../cayenne-guide/src/docbkx/ext-jcache.xml     |  61 ++
 .../cayenne-guide/src/docbkx/ext-joda.xml       |  53 ++
 docs/docbook/cayenne-guide/src/docbkx/index.xml |   1 +
 docs/docbook/cayenne-guide/src/docbkx/part5.xml |  30 +
 .../cayenne-guide/src/docbkx/queries-custom.xml |  57 ++
 .../cayenne-guide/src/docbkx/queries-ejbql.xml  |  94 +++
 .../cayenne-guide/src/docbkx/queries-mapped.xml |  44 ++
 .../src/docbkx/queries-namedquery.xml           |  35 +
 .../src/docbkx/queries-procedure.xml            |  67 ++
 .../src/docbkx/queries-procedurecall.xml        |  61 ++
 .../cayenne-guide/src/docbkx/queries-select.xml | 111 ++++
 .../src/docbkx/queries-selectbyid.xml           |  33 +
 .../src/docbkx/queries-sqlselect.xml            |  45 ++
 .../src/docbkx/queries-sqltemplate.xml          | 420 ++++++++++++
 .../cayenne-guide/src/docbkx/queries.xml        | 632 +------------------
 docs/docbook/cayenne-guide/src/docbkx/setup.xml |   5 +
 .../src/images/ext-crypto-obj-entity.png        | Bin 0 -> 18145 bytes
 .../cayenne-guide/src/images/ext-dbcp-setup.png | Bin 0 -> 33026 bytes
 .../upgrade-guide/src/docbkx/new-features.xml   |  57 +-
 26 files changed, 1719 insertions(+), 670 deletions(-)
----------------------------------------------------------------------



[08/10] cayenne git commit: Change 4.0.M6 to 4.0.B1

Posted by nt...@apache.org.
Change 4.0.M6 to 4.0.B1


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/8df7c5d2
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/8df7c5d2
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/8df7c5d2

Branch: refs/heads/STABLE-4.0
Commit: 8df7c5d2727493b751e771275edb033e001940d7
Parents: dbd733a
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Sep 22 17:29:05 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Sep 22 17:29:05 2017 +0300

----------------------------------------------------------------------
 docs/doc/src/main/resources/UPGRADE.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/8df7c5d2/docs/doc/src/main/resources/UPGRADE.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/UPGRADE.txt b/docs/doc/src/main/resources/UPGRADE.txt
index f241f00..45ae5d1 100644
--- a/docs/doc/src/main/resources/UPGRADE.txt
+++ b/docs/doc/src/main/resources/UPGRADE.txt
@@ -5,7 +5,7 @@ IMPORTANT: be sure to read all notes for the intermediate releases between your
            current release and the release you are upgrading to.
 -------------------------------------------------------------------------------
 
-UPGRADING TO 4.0.M6
+UPGRADING TO 4.0.B1
 
 * Per CAY-2302 postcommit module and all it's internals renamed to commitlog.
       Most important change is the new @CommitLog annotation which should be used instead of @Auditable,


[06/10] cayenne git commit: Fix code example

Posted by nt...@apache.org.
Fix code example

(cherry picked from commit 72e9ba6)


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/5e370208
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/5e370208
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/5e370208

Branch: refs/heads/STABLE-4.0
Commit: 5e370208d449bb5613e3a7144d769b7d2429865c
Parents: 54fc997
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Sep 22 11:43:45 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Sep 22 17:05:15 2017 +0300

----------------------------------------------------------------------
 docs/docbook/cayenne-guide/src/docbkx/queries-select.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e370208/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
index 87a265a..035fdb2 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
@@ -54,8 +54,8 @@ INFO: === returned 1 row. - took 6 ms.</screen>
         </para>
         <para>To order the results of ObjectSelect, one or more orderings can be applied:
             <programlisting language="java">List&lt;Artist> objects = ObjectSelect.query(Artist.class)
-    .addOrderBy(Artist.DATE_OF_BIRTH.desc())
-    .addOrderBy(Artist.NAME.asc())
+    .orderBy(Artist.DATE_OF_BIRTH.desc())
+    .orderBy(Artist.NAME.asc())
     .select(context);</programlisting>
         </para>
         <para>There's a number of other useful methods in ObjectSelect that define what to select


[05/10] cayenne git commit: ValueObjectType documentation + other minor additions

Posted by nt...@apache.org.
ValueObjectType documentation + other minor additions

(cherry picked from commit 1d58619)


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/54fc9975
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/54fc9975
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/54fc9975

Branch: refs/heads/STABLE-4.0
Commit: 54fc9975f354c36d434d202d0465054040cfac2d
Parents: afb731f
Author: Nikita Timofeev <st...@gmail.com>
Authored: Thu Sep 21 18:52:31 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Sep 22 17:05:05 2017 +0300

----------------------------------------------------------------------
 .../src/docbkx/customizing-cayenne-runtime.xml  | 152 ++++++++++++++-----
 1 file changed, 112 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/54fc9975/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml b/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml
index 3d3feb6..1ffdb3b 100644
--- a/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml
+++ b/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml
@@ -253,23 +253,90 @@ binder.bindList(DefaultDbAdapterFactory.DETECTORS_LIST)
                 this:<programlisting language="java">binder.bind(QueryCache.class).to(EhCacheQueryCache.class);</programlisting></para>
         </section>
     </section>
-    <section xml:id="extendedtypes">
-        <title>Extended Types</title>
-        <para>JDBC specification defines a set of "standard" database column types (defined in java.sql.Types class)
-            and a very specific mapping of these types to Java Object Types, such as java.lang.String,
-            java.math.BigDecimal, etc. Sometimes there is a need to use a custom Java type not known to JDBC driver and
-            Cayenne allows to configure it. For this Cayenne needs to know how to instantiate this type from
-            a database "primitive" value, and conversely, how to transform an object of the custom type to
-            a JDBC-compatible object.</para>
-        <section xml:id="supporting-non-standard-types">
-            <title>Supporting Non-Standard Types</title>
-            <para>For supporting non-standard type you should define it via an interface <code>org.apache.cayenne.access.types.ExtendedType</code>.
-                An implementation must provide <code>ExtendedType.getClassName()</code> method that returns
-                a fully qualified Java class name for the supported custom type, and a number of methods
-                that convert data between JDBC and custom type.
-                The following example demonstrates how to add a custom DoubleArrayType
-                to store java.lang.Double[] as a custom string in a database:</para>
-            <programlisting language="java">
+    <section>
+        <title>Using custom data types</title>
+        <section>
+            <title>Value object type</title>
+            <para>
+                <code>ValueObjectType</code> is a new and lightweight alternative to the Extended Types API described in the following section.
+                In most cases is should be preferred as is it easier to understand and use. Currently only one case is known when <code>ExtendedType</code> should be used:
+                when your value object can be mapped on different JDBC types.
+            </para>
+            <para>
+                In order to use your custom data type you should implement <code>ValueObjectType</code> describing it in terms of some type already known to Cayenne
+                (e.g. backed by system or user ExtendedType).
+                Let's assume we want to support some data type called <code>Money</code>:
+                <programlisting language="java"><![CDATA[public class Money {
+    private BigDecimal value;
+
+    public Money(BigDecimal value) {
+        this.value = value;
+    }
+
+    public BigDecimal getValue() {
+        return value;
+    }
+
+    // .. some other business logic ..
+}]]></programlisting>
+                Here is how <code>ValueObjectType</code> that will allow to store our <code>Money</code> class as <code>BigDecimal</code>
+                can be implemented:
+                <programlisting language="java"><![CDATA[public class MoneyValueObjectType implements ValueObjectType<Money, BigDecimal> {
+
+    @Override
+    public Class<BigDecimal> getTargetType() {
+        return BigDecimal.class;
+    }
+
+    @Override
+    public Class<Money> getValueType() {
+        return Money.class;
+    }
+
+    @Override
+    public Money toJavaObject(BigDecimal value) {
+        return new Money(value);
+    }
+
+    @Override
+    public BigDecimal fromJavaObject(Money object) {
+        return object.getValue();
+    }
+
+    @Override
+    public String toCacheKey(Money object) {
+        return object.getValue().toString();
+    }
+}]]></programlisting>
+            </para>
+            <para>
+                Last step is to register this new type in <code>ServerRuntime</code>:
+                <programlisting language="java"><![CDATA[ServerRuntime runtime = ServerRuntime.builder()
+    .addConfig("cayenne-project.xml")
+    .addModule(binder -> ServerModule.contributeValueObjectTypes(binder).add(MoneyValueObjectType.class))
+    .build();]]></programlisting>
+            </para>
+            <para>More examples of implementation you can find in
+                <!--<link xlink:href="https://github.com/apache/cayenne/tree/master/cayenne-java8">cayenne-java8 module</link> or-->
+                <link xlink:href="https://github.com/apache/cayenne/tree/master/cayenne-joda">cayenne-joda module</link>.</para>
+        </section>
+        <section xml:id="extendedtypes">
+            <title>Extended Types</title>
+            <para>JDBC specification defines a set of "standard" database column types (defined in java.sql.Types class)
+                and a very specific mapping of these types to Java Object Types, such as java.lang.String,
+                java.math.BigDecimal, etc. Sometimes there is a need to use a custom Java type not known to JDBC driver and
+                Cayenne allows to configure it. For this Cayenne needs to know how to instantiate this type from
+                a database "primitive" value, and conversely, how to transform an object of the custom type to
+                a JDBC-compatible object.</para>
+            <section xml:id="supporting-non-standard-types">
+                <title>Supporting Non-Standard Types</title>
+                <para>For supporting non-standard type you should define it via an interface <code>org.apache.cayenne.access.types.ExtendedType</code>.
+                    An implementation must provide <code>ExtendedType.getClassName()</code> method that returns
+                    a fully qualified Java class name for the supported custom type, and a number of methods
+                    that convert data between JDBC and custom type.
+                    The following example demonstrates how to add a custom DoubleArrayType
+                    to store <code>java.lang.Double[]</code> as a custom string in a database:</para>
+                <programlisting language="java">
 /**
 * Defines methods to read Java objects from JDBC ResultSets and write as parameters of
 * PreparedStatements.
@@ -336,42 +403,38 @@ public class DoubleArrayType implements ExtendedType {
         return res;
     }
 }
-            </programlisting>
-            <para>For Java7</para>
-            <programlisting language="java">
+                </programlisting>
+                <para>For Java7</para>
+                <programlisting language="java">
 // add DoubleArrayType to list of user types
 ServerRuntime runtime = ServerRuntime.builder()
                 .addConfig("cayenne-project.xml")
                 .addModule(new Module() {
                     @Override
                     public void configure(Binder binder) {
-                        binder
-                                .bindList(Constants.SERVER_USER_TYPES_LIST)
-                                .add(new DoubleArrayType());
+                        ServerModule.contributeUserTypes(binder).add(new DoubleArrayType());
                     }
                 })
                 .build();
-            </programlisting>
-            <para>For Java8</para>
-            <programlisting language="java">
+                </programlisting>
+                <para>For Java8</para>
+                <programlisting language="java">
 // add DoubleArrayType to list of user types
 ServerRuntime runtime = ServerRuntime.builder()
                 .addConfig("cayenne-project.xml")
-                .addModule(binder -> binder.bindList(Constants.SERVER_USER_TYPES_LIST).add(new DoubleArrayType()))
+                .addModule(binder -> ServerModule.contributeUserTypes(binder).add(new DoubleArrayType()))
                 .build();
-            </programlisting>
-            <para>More examples of implementation you can find in
-                <link xlink:href="https://github.com/apache/cayenne/tree/master/cayenne-java8">cayenne-java8 module</link> or
-                <link xlink:href="https://github.com/apache/cayenne/tree/master/cayenne-joda">cayenne-joda module</link>.</para>
-        </section>
-        <section xml:id="dbadapters-and-extended-types">
-            <title>DbAdapters and Extended Types</title>
-            <para>As shown in the example above, ExtendedTypes are stored by DbAdapter. In fact DbAdapters often install
-                their own extended types to address incompatibilities, incompleteness and differences between
-                JDBC drivers in handling "standard" JDBC types. For instance some drivers support reading large
-                character columns (CLOB) as java.sql.Clob, but some other - as "character stream", etc.
-                Adapters provided with Cayenne override <code>configureExtendedTypes()</code> method to install their own types,
-                possibly substituting Cayenne defaults. Custom DbAdapters can use the same technique.</para>
+                </programlisting>
+            </section>
+            <section xml:id="dbadapters-and-extended-types">
+                <title>DbAdapters and Extended Types</title>
+                <para>As shown in the example above, ExtendedTypes are stored by DbAdapter. In fact DbAdapters often install
+                    their own extended types to address incompatibilities, incompleteness and differences between
+                    JDBC drivers in handling "standard" JDBC types. For instance some drivers support reading large
+                    character columns (CLOB) as java.sql.Clob, but some other - as "character stream", etc.
+                    Adapters provided with Cayenne override <code>configureExtendedTypes()</code> method to install their own types,
+                    possibly substituting Cayenne defaults. Custom DbAdapters can use the same technique.</para>
+            </section>
         </section>
     </section>
     <section xml:id="noteworthy-runtime-components">
@@ -388,12 +451,21 @@ ServerRuntime runtime = ServerRuntime.builder()
         </section>
         <section xml:id="datasourcefactory">
             <title>DataSourceFactory</title>
+            <para>Factory that returns <code>javax.sql.DataSource</code> object based on the configuration provided in the
+                "nodeDescriptor".
+            </para>
         </section>
         <section xml:id="datachannelfilter">
             <title>DataChannelFilter</title>
+            <para> An interface of a filter that allows to intercept DataChannel operations. Filters allow
+                to implement chains of custom processors around a DataChannel, that can be used for
+                security, monitoring, business logic, providing context to lifecycle event listeners,
+                etc.
+            </para>
         </section>
         <section xml:id="querycache">
             <title>QueryCache</title>
+            <para>Defines API of a cache that stores query results.</para>
         </section>
     </section>
 </chapter>


[02/10] cayenne git commit: CYA_2173 Update fluent query API documentation

Posted by nt...@apache.org.
CYA_2173 Update fluent query API documentation

(cherry picked from commit d166a6a)


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/de255803
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/de255803
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/de255803

Branch: refs/heads/STABLE-4.0
Commit: de255803c6a454e579b24b0ed5419074a4ebb792
Parents: 5bd6b08
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Sep 1 14:17:58 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Sep 22 17:04:28 2017 +0300

----------------------------------------------------------------------
 .../cayenne-guide/src/docbkx/queries-custom.xml |  57 ++
 .../cayenne-guide/src/docbkx/queries-ejbql.xml  |  94 +++
 .../cayenne-guide/src/docbkx/queries-mapped.xml |  44 ++
 .../src/docbkx/queries-namedquery.xml           |  35 +
 .../src/docbkx/queries-procedure.xml            |  67 ++
 .../src/docbkx/queries-procedurecall.xml        |  61 ++
 .../cayenne-guide/src/docbkx/queries-select.xml | 111 ++++
 .../src/docbkx/queries-selectbyid.xml           |  33 +
 .../src/docbkx/queries-sqlselect.xml            |  45 ++
 .../src/docbkx/queries-sqltemplate.xml          | 420 ++++++++++++
 .../cayenne-guide/src/docbkx/queries.xml        | 632 +------------------
 11 files changed, 981 insertions(+), 618 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries-custom.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-custom.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-custom.xml
new file mode 100644
index 0000000..a8f00ea
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-custom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<section xmlns="http://docbook.org/ns/docbook" xml:id="custom-queries">
+        <title>Custom Queries</title>
+        <para>If a user needs some extra functionality not addressed by the existing set of Cayenne
+            queries, he can write his own. The only requirement is to implement
+                <code>org.apache.cayenne.query.Query</code> interface. The easiest way to go about
+            it is to subclass some of the base queries in Cayenne. </para>
+        <para>E.g. to do something directly in the JDBC layer, you might subclass
+            AbstractQuery:<programlisting language="java">public class MyQuery extends AbstractQuery {
+
+    @Override
+    public SQLAction createSQLAction(SQLActionVisitor visitor) {
+        return new SQLAction() {
+
+            @Override
+            public void performAction(Connection connection, OperationObserver observer) throws SQLException, Exception {
+                // 1. do some JDBC work using provided connection...
+                // 2. push results back to Cayenne via OperationObserver
+            }
+        };
+    }
+}</programlisting></para>
+        <para>To delegate the actual query execution to a standard Cayenne query, you may subclass
+            IndirectQuery:<programlisting language="java">public class MyDelegatingQuery extends IndirectQuery {
+
+    @Override
+    protected Query createReplacementQuery(EntityResolver resolver) {
+        SQLTemplate delegate = new SQLTemplate(SomeClass.class, generateRawSQL());
+        delegate.setFetchingDataRows(true);
+        return delegate;
+    }
+
+    protected String generateRawSQL() {
+        // build some SQL string
+    }
+}</programlisting></para>
+        <para>In fact many internal Cayenne queries are IndirectQueries, delegating to SelectQuery
+            or SQLTemplate after some preprocessing.</para>
+    </section>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries-ejbql.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-ejbql.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-ejbql.xml
new file mode 100644
index 0000000..4c0afff
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-ejbql.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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 "License"); 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 "AS IS" 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.
+-->
+<section xmlns="http://docbook.org/ns/docbook" xml:id="ejbqlquery">
+        <title>EJBQLQuery</title>
+        <para>EJBQLQuery was created as a part of an experiment in adopting some of Java Persistence
+            API (JPA) approaches in Cayenne. It is a parameterized object query that is created from
+            query String. A String used to build EJBQLQuery must conform to JPQL (JPA query
+            language):<programlisting language="java">EJBQLQuery query = new EJBQLQuery("select a FROM Artist a");</programlisting></para>
+        <para>JPQL details can be found in any JPA manual. Here we'll mention only how this fits
+            into Cayenne and what are the differences between EJBQL and other Cayenne
+            queries.</para>
+        <para>Although most frequently EJBQLQuery is used as an alternative to SelectQuery, there
+            are also DELETE and UPDATE varieties available. <note>
+                <para>As of this version of Cayenne, DELETE and UPDATE do not change the state of
+                    objects in the ObjectContext. They are run directly against the database
+                    instead. </para>
+            </note><programlisting language="java">EJBQLQuery select = new EJBQLQuery("select a FROM Artist a WHERE a.name = 'Salvador Dali'");
+List&lt;Artist> artists = context.performQuery(select);</programlisting><programlisting language="java">EJBQLQuery delete = new EJBQLQuery("delete from Painting");
+context.performGenericQuery(delete);</programlisting><programlisting language="java">EJBQLQuery update = new EJBQLQuery("UPDATE Painting AS p SET p.name = 'P2' WHERE p.name = 'P1'");
+context.performGenericQuery(update);</programlisting>In
+            most cases SelectQuery is preferred to EJBQLQuery, as it is API-based, and provides you
+            with better compile-time checks. However sometimes you may want a completely scriptable
+            object query. This is when you might prefer EJBQL. A more practical reason for picking
+            EJBQL over SelectQuery though is that the former offers some extra selecting
+            capabilities, namely aggregate functions and
+            subqueries:<programlisting language="java">EJBQLQuery query = new EJBQLQuery("select a, COUNT(p) FROM Artist a JOIN a.paintings p GROUP BY a");
+List&lt;Object[]> result = context.performQuery(query);
+for(Object[] artistWithCount : result) {
+    Artist a = (Artist) artistWithCount[0];
+    int hasPaintings = (Integer) artistWithCount[1];
+}</programlisting>This
+            also demonstrates a previously unseen type of select result - a List of Object[]
+            elements, where each entry in an Object[] is either a DataObject or a scalar, depending
+            on the query SELECT clause. A result can also be a list of
+            scalars:<programlisting language="java">EJBQLQuery query = new EJBQLQuery("select a.name FROM Artist a");
+List&lt;String> names = context.performQuery(query);</programlisting>
+
+            EJBQLQuery supports an "IN" clause with three different usage-patterns.  The following
+            example would require three individual positional parameters (named
+            parameters could also have been used) to be supplied.
+
+            <programlisting language="sql">select p from Painting p where p.paintingTitle in (?1,?2,?3)</programlisting>
+
+            The following example requires a single positional parameter to be supplied.  The
+            parameter can be any concrete implementation of the java.util.Collection interface such as
+            java.util.List or java.util.Set.
+
+            <programlisting language="sql">select p from Painting p where p.paintingTitle in ?1</programlisting>
+
+            The following example is functionally identical to the one prior.
+
+            <programlisting language="sql">select p from Painting p where p.paintingTitle in (?1)</programlisting>
+
+            </para>
+            <para>
+                It is <link linkend="expressions-to-ejbql">possible to convert</link>
+                an <link linkend="expressions">Expression</link>
+                object used with a <link linkend="selectquery">SelectQuery</link>
+                to EJBQL.  Use the Expression#appendAsEJBQL methods for this purpose.
+            </para>
+            <para>
+            While
+            Cayenne Expressions discussed previously can be thought of as identical to JPQL WHERE
+            clause, and indeed they are very close, there are a few noteable differences:
+            <itemizedlist>
+                <listitem>
+                    <para>Null handling: SelectQuery would translate the expressions matching NULL
+                        values to the corresponding "X IS NULL" or "X IS NOT NULL" SQL syntax.
+                        EJBQLQuery on the other hand requires explicit "IS NULL" (or "IS NOT NULL")
+                        syntax to be used, otherwise the generated SQL will look like "X = NULL" (or
+                        "X &lt;> NULL"), which will evaluate differently.</para>
+                </listitem>
+                <listitem>
+                    <para>Expression Parameters: SelectQuery uses "$" to denote named parameters
+                        (e.g. "$myParam"), while EJBQL uses ":" (e.g. ":myParam"). Also EJBQL
+                        supports positional parameters denoted by the question mark: "?3".</para>
+                </listitem>
+            </itemizedlist>
+        </para>
+    </section>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries-mapped.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-mapped.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-mapped.xml
new file mode 100644
index 0000000..b80e828
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-mapped.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<section xmlns="http://docbook.org/ns/docbook" xml:id="mappedqueries">
+    <title>MappedSelect and MappedExec</title>
+    <para>
+        <code>MappedSelect</code> and <code>MappedExec</code> is a queries that are just a reference to another queries stored in the DataMap.
+        The actual stored query can be SelectQuery, SQLTemplate, EJBQLQuery, etc.
+        Difference between <code>MappedSelect</code> and <code>MappedExec</code> is (as reflected in their names)
+        whether underlying query intended to select data or just to perform some generic SQL code.
+        <note>
+            <para>This queries are "fluent" versions of deprecated <code>NamedQuery</code> class.</para>
+        </note>
+    </para>
+    <para>
+        Here is example of how to use <code>MappedSelect</code>:
+        <programlisting language="java"><![CDATA[List<Artist> results = MappedSelect.query("artistsByName", Artist.class)

+    .param("name", "Picasso")

+    .select(context);]]></programlisting>
+    </para>
+    <para>
+        And here is example of <code>MappedExec</code>:
+        <programlisting language="java"><![CDATA[QueryResult result = MappedExec.query("updateQuery")

+    .param("var", "value")

+    .execute(context);
+System.out.println("Rows updated: " + result.firstUpdateCount());]]></programlisting>
+    </para>
+</section>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries-namedquery.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-namedquery.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-namedquery.xml
new file mode 100644
index 0000000..2287413
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-namedquery.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<section xmlns="http://docbook.org/ns/docbook" xml:id="namedquery">
+            <title>NamedQuery</title>
+        <para>NamedQuery is a query that is a reference to another query stored in the DataMap. The
+            actual stored query can be SelectQuery, SQLTemplate, EJBQLQuery, etc. It doesn't matter
+            - the API for calling them is the same - via a
+            NamedQuery:<programlisting language="java">String[] keys = new String[] {"loginid", "password"};
+Object[] values = new String[] {"joe", "secret"};
+
+NamedQuery query = new NamedQuery("Login", keys, values);
+
+List&lt;User> matchingUsers = context.performQuery(query); </programlisting>
+            <warning>
+                <para>This query is deprecated in favor of <code>MappedSelect</code> and <code>MappedExec</code></para>
+            </warning>
+        </para>
+    </section>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries-procedure.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-procedure.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-procedure.xml
new file mode 100644
index 0000000..dea2ce8
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-procedure.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<section xmlns="http://docbook.org/ns/docbook" xml:id="procedurequery">
+    <title>ProcedureQuery</title>
+    <para>Stored procedures are mapped as separate objects in CayenneModeler. ProcedureQuery
+        provides a way to execute them with a certain set of parameters. Just like with
+        SQLTemplate, the outcome of a procedure can be anything - a single result set, mutliple
+        result sets, some data modification (returned as an update count), or a combination of
+        these. So use "performQuery" to get a single result set, and use "performGenericQuery"
+        for anything
+        else:<programlisting language="java">ProcedureQuery query = new ProcedureQuery("my_procedure", Artist.class);
+
+// Set "IN" parameter values
+query.addParam("p1", "abc");
+query.addParam("p2", 3000);
+
+List&lt;Artist> result = context.performQuery(query);</programlisting><programlisting language="java">// here we do not bother with root class.
+// Procedure name gives us needed routing information
+ProcedureQuery query = new ProcedureQuery("my_procedure");
+
+query.addParam("p1", "abc");
+query.addParam("p2", 3000);
+
+QueryResponse response = context.performGenericQuery(query); </programlisting></para>
+    <para>A stored procedure can return data back to the application as result sets or via OUT
+        parameters. To simplify the processing of the query output, QueryResponse treats OUT
+        parameters as if it was a separate result set. If a stored procedure declares any OUT or
+        INOUT parameters, QueryResponse will contain their returned values in the very first
+        result
+        list:<programlisting language="java">ProcedureQuery query = new ProcedureQuery("my_procedure");
+QueryResponse response = context.performGenericQuery(query);
+
+// read OUT parameters
+List out = response.firstList();
+
+if(!out.isEmpty()) {
+    Map outParameterValues = (Map) outList.get(0);
+}</programlisting></para>
+    <para>There maybe a situation when a stored procedure handles its own transactions, but an
+        application is configured to use Cayenne-managed transactions. This is obviously
+        conflicting and undesirable behavior. In this case ProcedureQueries should be executed
+        explicitly wrapped in an "external" Transaction. This is one of the few cases when a
+        user should worry about transactions at all. See Transactions section for more
+        details.</para>
+    <para>
+        <warning>
+            <para>This query is superseded by <code>ProcedureCall</code> and generally shouldn't be used.</para>
+        </warning>
+    </para>
+</section>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries-procedurecall.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-procedurecall.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-procedurecall.xml
new file mode 100644
index 0000000..394a21e
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-procedurecall.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<section xmlns="http://docbook.org/ns/docbook" xml:id="procedurecallquery">
+    <title>ProcedureCall</title>
+    <para>Stored procedures are mapped as separate objects in CayenneModeler. <code>ProcedureCall</code>
+        provides a way to execute them with a certain set of parameters. This query is a "fluent" version of
+        older <code>ProcedureQuery</code>.
+        Just like with <code>SQLTemplate</code>, the outcome of a procedure can be anything - a single result set, multiple
+        result sets, some data modification (returned as an update count), or a combination of these.
+        So use root class to get a single result set, and use only procedure name
+        for anything else:
+        <programlisting language="java"><![CDATA[List<Artist> result = ProcedureCall.query("my_procedure", Artist.class)
+    .param("p1", "abc")
+    .param("p2", 3000)
+    .call(context)
+    .firstList();]]></programlisting>
+
+        <programlisting language="java"><![CDATA[// here we do not bother with root class.
+// Procedure name gives us needed routing information
+ProcedureResult result = ProcedureCall.query("my_procedure")
+    .param("p1", "abc")
+    .param("p2", 3000)
+    .call();]]></programlisting>
+    </para>
+    <para>A stored procedure can return data back to the application as result sets or via OUT
+        parameters. To simplify the processing of the query output, QueryResponse treats OUT
+        parameters as if it was a separate result set. For stored procedures declaref any OUT or
+        INOUT parameters, <code>ProcedureResult</code> have convenient utility method to get them:
+        <programlisting language="java">ProcedureResult result = ProcedureCall.query("my_procedure")
+    .call(context);
+
+// read OUT parameters
+Object out = result.getOutParam("out_param");
+</programlisting>
+    </para>
+    <para>
+        There maybe a situation when a stored procedure handles its own transactions, but an
+        application is configured to use Cayenne-managed transactions. This is obviously
+        conflicting and undesirable behavior. In this case ProcedureQueries should be executed
+        explicitly wrapped in an "external" Transaction. This is one of the few cases when a
+        user should worry about transactions at all. See Transactions section for more
+        details.
+    </para>
+</section>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
new file mode 100644
index 0000000..87a265a
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-select.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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 "License"); 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 "AS IS" 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.
+-->
+<section xmlns="http://docbook.org/ns/docbook" xml:id="selectquery">
+    <title>ObjectSelect</title>
+    <section>
+        <title>Selecting objects</title>
+        <para>
+            <emphasis role="italic">ObjectSelect supersedes older SelectQuery. SelectQuery is still
+                available and supported. </emphasis>
+        </para>
+        <para>ObjectSelect is the most commonly used query in Cayenne applications. This may be the
+            only query you will ever need. It returns a list of persistent objects (or data rows) of
+            a certain type specified in the
+            query:
+            <programlisting language="java">List&lt;Artist> objects = ObjectSelect.query(Artist.class).select(context);</programlisting>
+            This returned all rows in the "ARTIST" table. If the logs were turned on, you might see the
+            following SQL printed:
+            <screen>INFO: SELECT t0.DATE_OF_BIRTH, t0.NAME, t0.ID FROM ARTIST t0
+INFO: === returned 5 row. - took 5 ms.</screen>
+        </para>
+        <para>This SQL was generated by Cayenne from the ObjectSelect above. ObjectSelect can have a
+            qualifier to select only the data matching specific criteria. Qualifier is simply an
+            Expression (Expressions where discussed in the previous chapter), appended to the query
+            using "where" method. If you only want artists whose name begins with 'Pablo', you might
+            use the following qualifier expression:
+            <programlisting language="java">List&lt;Artist> objects = ObjectSelect.query(Artist.class)
+    .where(Artist.NAME.like("Pablo%"))
+    .select(context);</programlisting>
+            The SQL will look different this time:
+            <screen>INFO: SELECT t0.DATE_OF_BIRTH, t0.NAME, t0.ID FROM ARTIST t0 WHERE t0.NAME LIKE ?
+[bind: 1->NAME:'Pablo%']
+INFO: === returned 1 row. - took 6 ms.</screen>
+        </para>
+        <para>ObjectSelect allows to assemble qualifier from parts, using "and" and "or" method to
+            chain then together:
+            <programlisting language="java">List&lt;Artist> objects = ObjectSelect.query(Artist.class)
+    .where(Artist.NAME.like("A%"))
+    .and(Artist.DATE_OF_BIRTH.gt(someDate)
+    .select(context);</programlisting>
+        </para>
+        <para>To order the results of ObjectSelect, one or more orderings can be applied:
+            <programlisting language="java">List&lt;Artist> objects = ObjectSelect.query(Artist.class)
+    .addOrderBy(Artist.DATE_OF_BIRTH.desc())
+    .addOrderBy(Artist.NAME.asc())
+    .select(context);</programlisting>
+        </para>
+        <para>There's a number of other useful methods in ObjectSelect that define what to select
+            and how to optimize database interaction (prefetching, caching, fetch offset and limit,
+            pagination, etc.). Some of them are discussed in separate chapters on caching and
+            performance optimization. Others are fairly self-explanatory. Please check the API docs
+            for the full extent of the ObjectSelect features.
+        </para>
+    </section>
+    <section>
+        <title>Selecting individual columns</title>
+        <para>
+            <code>ObjectSelect</code> query can be used to fetch individual properties of objects via
+            type-safe API:
+            <programlisting language="java"><![CDATA[List<String> names = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME)
+    .select(context);]]></programlisting>
+            And here is example of selecting several properties, note that result will be <code>Object[]</code>:
+            <programlisting language="java"><![CDATA[List<Object[]> nameAndDate = ObjectSelect
+    .columnQuery(Artist.class, Artist.ARTIST_NAME, Artist.DATE_OF_BIRTH)
+    .select(context);]]></programlisting>
+        </para>
+    </section>
+    <section>
+        <title>Selecting using aggregate functions</title>
+        <para>
+            ObjectSelect query supports usage of aggregate functions.
+            Most common variant of aggregation is selecting count of records, this can be done really easy:
+            <programlisting language="java"><![CDATA[long count = ObjectSelect.query(Artist.class).selectCount(context);]]></programlisting>
+            But you can use aggregates in more cases, even combine selecting individual properties and aggregates:
+            <programlisting language="java"><![CDATA[// this is artificial property signaling that we want to get full object
+Property<Artist> artistProperty = Property.createSelf(Artist.class);
+
+List<Object[]> artistAndPaintingCount = ObjectSelect.columnQuery(Artist.class, artistProperty, Artist.PAINTING_ARRAY.count())
+    .where(Artist.ARTIST_NAME.like("a%"))
+    .having(Artist.PAINTING_ARRAY.count().lt(5L))
+    .orderBy(Artist.PAINTING_ARRAY.count().desc(), Artist.ARTIST_NAME.asc())
+    .select(context);
+
+for(Object[] next : artistAndPaintingCount) {
+    Artist artist = (Artist)next[0];
+    long paintings = (Long)next[1];
+    System.out.println(artist.getArtistName() + " have " + paintings + " paintings");
+}]]></programlisting>
+            Here is generated <code>SQL</code> for this query:
+            <programlisting language="sql">SELECT DISTINCT t0.ARTIST_NAME, t0.DATE_OF_BIRTH, t0.ARTIST_ID, COUNT(t1.PAINTING_ID)
+FROM ARTIST t0 JOIN PAINTING t1 ON (t0.ARTIST_ID = t1.ARTIST_ID)
+WHERE t0.ARTIST_NAME LIKE ?
+GROUP BY t0.ARTIST_NAME, t0.ARTIST_ID, t0.DATE_OF_BIRTH
+HAVING COUNT(t1.PAINTING_ID) &lt; ?
+ORDER BY COUNT(t1.PAINTING_ID) DESC, t0.ARTIST_NAME</programlisting>
+        </para>
+    </section>
+</section>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries-selectbyid.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-selectbyid.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-selectbyid.xml
new file mode 100644
index 0000000..59940f9
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-selectbyid.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<section xmlns="http://docbook.org/ns/docbook" xml:id="selectbyid">
+    <title>SelectById</title>
+    <para>
+        This query allows to search objects by their ID.
+        It's introduced in Cayenne 4.0 and uses new "fluent" API same as <code>ObjectSelect</code> query.
+    </para>
+    <para>
+        Here is example of how to use it:
+        <programlisting language="java"><![CDATA[Artist artistWithId1 = SelectById.query(Artist.class, 1)
+    .prefetch(Artist.PAINTING_ARRAY.joint())
+    .localCache()
+    .selectOne(context);]]></programlisting>
+    </para>
+</section>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries-sqlselect.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-sqlselect.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-sqlselect.xml
new file mode 100644
index 0000000..20be436
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-sqlselect.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~   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
+  ~  "License"); 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
+  ~  "AS IS" 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sqlselect">
+    <title>SQLSelect and SQLExec</title>
+    <para>
+        <code>SQLSelect</code> and <code>SQLExec</code> are essentially a "fluent" versions of older <code>SQLTemplate</code> query.
+        <code>SQLSelect</code> can be used (as name suggests) to select custom data in form of entities, separate columns or collection of <code>DataRow</code>.
+        <code>SQLExec</code> is designed to just execute any raw SQL code (e.g. updates, deletes, DDLs, etc.)
+        This queries support all directives described in <link linkend="sqltemplate">SQLTemplate</link> section.
+    </para>
+    <para>
+        Here is example of how to use <code>SQLSelect</code>:
+        <programlisting language="java"><![CDATA[SQLSelect<Painting> q1 = SQLSelect
+    .query(Painting.class, "SELECT * FROM PAINTING WHERE PAINTING_TITLE LIKE #bind($title)")
+    .params("title", "painting%")
+    .upperColumnNames()
+    .localCache()
+    .limit(100)
+    .select(context);]]></programlisting>
+    </para>
+    <para>
+        And here is example of how to use <code>SQLExec</code>:
+        <programlisting language="java"><![CDATA[int inserted = SQLExec
+    .query("INSERT INTO ARTIST (ARTIST_ID, ARTIST_NAME) VALUES (#bind($id), #bind($name))")
+    .paramsArray(55, "Picasso")
+    .update(context);]]></programlisting>
+    </para>
+</section>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/de255803/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml b/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
new file mode 100644
index 0000000..4d0b21c
--- /dev/null
+++ b/docs/docbook/cayenne-guide/src/docbkx/queries-sqltemplate.xml
@@ -0,0 +1,420 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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 "License"); 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 "AS IS" 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.
+-->
+<section xmlns="http://docbook.org/ns/docbook" xml:id="sqltemplate">
+        <title>SQLTemplate</title>
+        <para>SQLTemplate is a query that allows to run native SQL from a Cayenne application. It
+            comes handy when the standard ORM concepts are not sufficient for a given query or an
+            update. SQL is too powerful and allows to manipulate data in ways that are not easily
+            described as a graph of related entities. Cayenne acknowledges this fact and provides
+            this facility to execute SQL, mapping the result to objects when possible. Here are
+            examples of selecting and non-selecting
+            SQLTemplates:<programlisting language="java">SQLTemplate select = new SQLTemplate(Artist.class, "select * from ARTIST");
+List&lt;Artist> result = context.performQuery(select);</programlisting><programlisting language="java">SQLTemplate update = new SQLTemplate(Artist.class, "delete from ARTIST");
+QueryResponse response = context.performGenericQuery(update);</programlisting></para>
+        <para>Cayenne doesn't make any attempt to make sense of the SQL semantics, so it doesn't
+            know whether a given query is performing a select or update, etc. It is the the user's
+            decision to run a given query as a selecting or "generic".</para>
+        <para>
+            <note>
+                <para>Any data modifications done to DB as a result of SQLTemplate execution do not
+                    change the state of objects in the ObjectContext. So some objects in the context
+                    may become stale as a result.</para>
+            </note>
+        </para>
+        <para>Another point to note is that the first argument to the SQLTemplate constructor - the
+            Java class - has the same meaning as in SelectQuery only when the result can be
+            converted to objects (e.g. when this is a selecting query and it is selecting all
+            columns from one table). In this case it denotes the "root" entity of this query result.
+            If the query does not denote a single entity result, this argument is only used for
+            query routing, i.e. determining which database it should be run against. You are free to
+            use any persistent class or even a DataMap instance in such situation. It will work as
+            long as the passed "root" maps to the same database as the current query.</para>
+        <para>To achieve interoperability between mutliple RDBMS a user can specify multiple SQL
+            statements for the same SQLTemplate, each corresponding to a native SQL dialect. A key
+            used to look up the right dialect during execution is a fully qualified class name of
+            the corresponding DbAdapter. If no DB-specific statement is present for a given DB, a
+            default generic statement is used. E.g. in all the examples above a default statement
+            will be used regardless of the runtime database. So in most cases you won't need to
+            explicitly "translate" your SQL to all possible dialects. Here is how this works in
+            practice:<programlisting language="java">SQLTemplate select = new SQLTemplate(Artist.class, "select * from ARTIST");
+
+// For Postgres it would be nice to trim padding of all CHAR columns.
+// Otherwise those will be returned with whitespace on the right.
+// assuming "NAME" is defined as CHAR...
+String pgSQL = "SELECT ARTIST_ID, RTRIM(NAME), DATE_OF_BIRTH FROM ARTIST";
+query.setTemplate(PostgresAdapter.class.getName(), pgSQL);</programlisting></para>
+
+        <section xml:id="sqltemplate-scripting">
+            <title>Scripting SQLTemplate with Velocity</title>
+            <para>The most interesting aspect of SQLTemplate (and the reason why it is called a
+                "template") is that a SQL string is treated by Cayenne as an Apache Velocity
+                template. Before sending it to DB as a PreparedStatement, the String is evaluated in
+                the Velocity context, that does variable substitutions, and performs special
+                callbacks in response to various directives, thus controlling query interaction with
+                the JDBC layer. </para>
+            <para>Check Velocity docs for the syntax details. Here we'll just mention the two main
+                scripting elements - "variables" (that look like <code>$var</code>) and "directives"
+                (that look like <code>#directive(p1 p2 p3)</code>). All built-in Velocity directives
+                are supported. Additionally Cayenne defines a number of its own directives to bind
+                parameters to PreparedStatements and to control the structure of the ResultSet.
+                These directives are described in the following sections.</para>
+        </section>
+        <section xml:id="sqltemplate-parameters">
+            <title>Variable Substitution</title>
+            <para>All variables in the template string are replaced from query
+                parameters:<programlisting language="java">SQLTemplate query = new SQLTemplate(Artist.class, "delete from $tableName");
+query.setParameters(Collections.singletonMap("tableName", "mydb.PAINTING"));
+
+// this will generate SQL like this: "delete from mydb.PAINTING"</programlisting>The
+                example above demonstrates the point made earlier in this chapter - even if we don't
+                know upfront which table the query will run against, we can still use a fixed "root"
+                in constructor (<code>Artist.class</code> in this case) , as we are not planning on
+                converting the result to objects.</para>
+            <para>Variable substitution within the text uses "<code>object.toString()</code>" method to replace the
+                variable value. Keep in mind that this may not be appropriate in all situations.
+                E.g. passing a date object in a WHERE clause expression may be converted to a String
+                not understood by the target RDBMS SQL parser. In such cases variable should be wrapped in <code>#bind</code>
+                directive as described below.</para>
+        </section>
+        <section xml:id="sqltemplate-bind-directive">
+            <title>Directives</title>
+            <para>These are the Cayenne directives used to customize SQLTemplate parsing and
+                integrate it with the JDBC layer: </para>
+            <section>
+                <title>#bind</title>
+                <para>Creates a PreparedStatement positional parameter in place of the directive,
+                    binding the value to it before statement execution. <code>#bind</code> is
+                    allowed in places where a "?" would be allowed in a PreparedStatement. And in
+                    such places it almost always makes sense to pass objects to the template via
+                    this or other forms of <code>#bind</code> instead of inserting them
+                    inline.</para>
+                <para><emphasis role="italic">Semantics:</emphasis></para>
+                <programlisting language="java">#bind(value)
+#bind(value jdbcType)
+#bind(value jdbcType scale)</programlisting>
+                <para><emphasis role="italic">Arguments:</emphasis>
+                    <itemizedlist>
+                        <listitem>
+                            <para><code>value</code> - can either be a char constant or a variable
+                                that is resolved from the query parameters. Note that the variable
+                                can be a collection, that will be automatically expanded into a list
+                                of individual value bindings. This is useful for instance to build
+                                IN conditions. </para>
+                        </listitem>
+                        <listitem>
+                            <para><code>jdbcType</code> - is a JDBC data type of the parameter as
+                                defined in <code>java.sql.Types</code>.</para>
+                        </listitem>
+                        <listitem>
+                            <para><code>scale</code> - An optional scale of the numeric value. Same
+                                as "scale" in PreparedStatement.</para>
+                        </listitem>
+                    </itemizedlist></para>
+                <para>
+                    <emphasis role="italic"
+                    >Usage</emphasis>:<programlisting language="java">#bind($xyz)
+#bind('str')
+#bind($xyz 'VARCHAR')
+#bind($xyz 'DECIMAL' 2)</programlisting></para>
+                <para><emphasis role="italic">Full
+                    example:</emphasis><programlisting language="sql">update ARTIST set NAME = #bind($name) where ID = #bind($id)</programlisting></para>
+            </section>
+            <section>
+                <title>#bindEqual</title>
+                <para>Same as #bind, but also includes the "=" sign in front of the value binding.
+                    Look at the example below - we took the #bind example and replaced "<code>ID =
+                        #bind(..)</code>" with "<code>ID #bindEqual(..)</code>". While it looks like
+                    a clumsy shortcut to eliminate the equal sign, the actual reason why this is
+                    useful is that it allows the value to be null. If the value is not null,
+                        "<code>= ?</code>" is generated, but if it is, the resulting chunk of the
+                    SQL would look like "<code>IS NULL</code>" and will be compilant with what the
+                    DB expects.</para>
+                <para><emphasis role="italic">Semantics:</emphasis></para>
+                <programlisting language="java">#bindEqual(value)
+#bindEqual(value jdbcType)
+#bindEqual(value jdbcType scale)</programlisting>
+                <para><emphasis role="italic">Arguments: (same as #bind)</emphasis>
+                </para>
+                <para>
+                    <emphasis role="italic"
+                    >Usage</emphasis>:<programlisting language="java">#bindEqual($xyz)
+#bindEqual('str')
+#bindEqual($xyz 'VARCHAR')
+#bindEqual($xyz 'DECIMAL' 2)</programlisting></para>
+                <para><emphasis role="italic">Full
+                    example:</emphasis><programlisting language="sql">update ARTIST set NAME = #bind($name) where ID #bindEqual($id)</programlisting></para>
+            </section>
+            <section>
+                <title>#bindNotEqual</title>
+                <para>This directive deals with the same issue as <code>#bindEqual</code> above,
+                    only it generates "not equal" in front of the value (or IS NOT NULL).</para>
+                <para><emphasis role="italic">Semantics:</emphasis></para>
+                <programlisting language="java">#bindNotEqual(value)
+#bindNotEqual(value jdbcType)
+#bindNotEqual(value jdbcType scale)</programlisting>
+                <para><emphasis role="italic">Arguments: (same as #bind)</emphasis></para>
+                <para>
+                    <emphasis role="italic"
+                    >Usage</emphasis>:<programlisting language="java">#bindNotEqual($xyz)
+#bindNotEqual('str')
+#bindNotEqual($xyz 'VARCHAR')
+#bindNotEqual($xyz 'DECIMAL' 2)</programlisting></para>
+                <para><emphasis role="italic">Full
+                    example:</emphasis><programlisting language="sql">update ARTIST set NAME = #bind($name) where ID #bindEqual($id)</programlisting></para>
+            </section>
+            <section>
+                <title>#bindObjectEqual</title>
+                <para>It can be tricky to use a Persistent object or an ObjectId in a binding,
+                    especially for tables with compound primary keys. This directive helps to handle
+                    such binding. It maps columns in the query to the names of Persistent object ID
+                    columns, extracts ID values from the object, and generates SQL like "COL1 = ?
+                    AND COL2 = ? ..." , binding positional parameters to ID values. It can also
+                    correctly handle null object. Also notice how we are specifying a Velocity array
+                    for multi-column PK.</para>
+                <para><emphasis role="italic">Semantics:</emphasis></para>
+                <programlisting language="java">#bindObjectEqual(value columns idColumns)</programlisting>
+                <para><emphasis role="italic">Arguments:</emphasis>
+                    <itemizedlist>
+                        <listitem>
+                            <para><code>value</code> - must be a variable that is resolved from the
+                                query parameters to a Persistent or ObjectId.</para>
+                        </listitem>
+                        <listitem>
+                            <para><code>columns</code> - the names of the columns to generate in the
+                                SQL.</para>
+                        </listitem>
+                        <listitem>
+                            <para><code>idColumn</code> - the names of the ID columns for a given
+                                entity. Must match the order of "columns" to match against.</para>
+                        </listitem>
+                    </itemizedlist></para>
+                <para>
+                    <emphasis role="italic"
+                    >Usage</emphasis>:<programlisting language="java">#bindObjectEqual($a 't0.ID' 'ID')
+#bindObjectEqual($b ['t0.FK1', 't0.FK2'] ['PK1', 'PK2'])</programlisting></para>
+                <para><emphasis role="italic">Full
+                    example:</emphasis><programlisting language="java">String sql = "SELECT * FROM PAINTING t0 WHERE #bindObjectEqual($a 't0.ARTIST_ID' 'ARTIST_ID' ) ORDER BY PAINTING_ID";
+SQLTemplate select = new SQLTemplate(Artist.class, sql);
+
+Artist a = ....
+select.setParameters(Collections.singletonMap("a", a)); </programlisting></para>
+            </section>
+            <section>
+                <title>#bindObjectNotEqual</title>
+                <para>Same as #bindObjectEqual above, only generates "not equal" operator for value
+                    comparison (or IS NOT NULL).</para>
+                <para><emphasis role="italic">Semantics:</emphasis></para>
+                <programlisting language="java">#bindObjectNotEqual(value columns idColumns)</programlisting>
+                <para><emphasis role="italic">Arguments: (same as #bindObjectEqual)</emphasis>
+                </para>
+                <para>
+                    <emphasis role="italic"
+                    >Usage</emphasis>:<programlisting language="java">#bindObjectNotEqual($a 't0.ID' 'ID')
+#bindObjectNotEqual($b ['t0.FK1', 't0.FK2'] ['PK1', 'PK2'])</programlisting></para>
+                <para><emphasis role="italic">Full
+                    example:</emphasis><programlisting language="java">String sql = "SELECT * FROM PAINTING t0 WHERE #bindObjectNotEqual($a 't0.ARTIST_ID' 'ARTIST_ID' ) ORDER BY PAINTING_ID";
+SQLTemplate select = new SQLTemplate(Artist.class, sql);
+
+Artist a = ....
+select.setParameters(Collections.singletonMap("a", a)); </programlisting></para>
+            </section>
+            <section>
+                <title>#result</title>
+                <para>Renders a column in SELECT clause of a query and maps it to a key in the
+                    result DataRow. Also ensures the value read is of the correct type. This allows
+                    to create a DataRow (and ultimately - a persistent object) from an arbitrary
+                    ResultSet.</para>
+                <para><emphasis role="italic">Semantics:</emphasis></para>
+                <programlisting language="java">#result(column)
+#result(column javaType)
+#result(column javaType alias)
+#result(column javaType alias dataRowKey)</programlisting>
+                <para><emphasis role="italic">Arguments:</emphasis>
+                    <itemizedlist>
+                        <listitem>
+                            <para><code>column</code> - the name of the column to render in SQL
+                                SELECT clause.</para>
+                        </listitem>
+                        <listitem>
+                            <para><code>javaType</code> - a fully-qualified Java class name for a
+                                given result column. For simplicity most common Java types used in
+                                JDBC can be specified without a package. These include all numeric
+                                types, primitives, String, SQL dates, BigDecimal and BigInteger. So
+                                    "<code>#result('A' 'String')</code>", "<code>#result('B'
+                                    'java.lang.String')</code>" and "<code>#result('C'
+                                'int')</code>" are all valid</para>
+                        </listitem>
+                        <listitem>
+                            <para><code>alias</code> - specifies both the SQL alias of the column
+                                and the value key in the DataRow. If omitted, "column" value is
+                                used.</para>
+                        </listitem>
+                        <listitem>
+                            <para><code>dataRowKey</code> - needed if SQL 'alias' is not appropriate
+                                as a DataRow key on the Cayenne side. One common case when this
+                                happens is when a DataRow retrieved from a query is mapped using
+                                joint prefetch keys (see below). In this case DataRow must use
+                                database path expressions for joint column keys, and their format is
+                                incompatible with most databases alias format. </para>
+                        </listitem>
+                    </itemizedlist></para>
+                <para>
+                    <emphasis role="italic"
+                    >Usage</emphasis>:<programlisting language="java">#result('NAME')
+#result('DATE_OF_BIRTH' 'java.util.Date')
+#result('DOB' 'java.util.Date' 'DATE_OF_BIRTH')
+#result('DOB' 'java.util.Date' '' 'artist.DATE_OF_BIRTH')
+#result('SALARY' 'float') </programlisting></para>
+                <para><emphasis role="italic">Full
+                    example:</emphasis><programlisting language="sql">SELECT #result('ID' 'int'), #result('NAME' 'String'), #result('DATE_OF_BIRTH' 'java.util.Date') FROM ARTIST</programlisting></para>
+            </section>
+            <section>
+                <title>#chain and #chunk</title>
+
+                    <para><code>#chain</code> and <code>#chunk</code> directives are used for
+                    conditional inclusion of SQL code. They are used together with
+                        <code>#chain</code> wrapping multiple <code>#chunks</code>. A chunk
+                    evaluates its parameter expression and if it is NULL suppresses rendering of the
+                    enclosed SQL block. A chain renders its prefix and its chunks joined by the
+                    operator. If all the chunks are suppressed, the chain itself is suppressed. This
+                    allows to work with otherwise hard to script SQL semantics. E.g. a WHERE clause
+                    can contain multiple conditions joined with AND or OR. Application code would
+                    like to exclude a condition if its right-hand parameter is not present (similar
+                    to Expression pruning discussed above). If all conditions are excluded, the
+                    entire WHERE clause should be excluded. chain/chunk allows to do that.</para>
+                    <para>
+                    <emphasis role="italic"
+                    >Semantics</emphasis>:<programlisting language="java">#chain(operator) ... #end
+#chain(operator prefix) ... #end
+#chunk() ... #end
+#chunk(param) ... #end </programlisting></para>
+                    <para><emphasis role="italic">Full
+                    example:</emphasis><programlisting language="java">#chain('OR' 'WHERE')
+	#chunk($name) NAME LIKE #bind($name) #end
+	#chunk($id) ARTIST_ID > #bind($id) #end
+#end" </programlisting></para>
+
+            </section>
+        </section>
+        <section>
+            <title>Mapping SQLTemplate Results</title>
+            <para>Here we'll discuss how to convert the data selected via SQLTemplate to some
+                useable format, compatible with other query results. It can either be very simple or
+                very complex, depending on the structure of the SQL, JDBC driver nature and the
+                desired result structure. This section presents various tips and tricks dealing with
+                result mapping. </para>
+            <para>By default SQLTemplate is expected to return a List of Persistent objects of its
+                root type. This is the simple
+                case:<programlisting language="java">SQLTemplate query = new SQLTemplate(Artist.class, "SELECT * FROM ARTIST");
+
+// List of Artists
+List&lt;Artist> artists = context.performQuery(query);</programlisting>Just
+                like SelectQuery, SQLTemplate can fetch DataRows. In fact DataRows option is very
+                useful with SQLTemplate, as the result type most often than not does not represent a
+                Cayenne entity, but instead may be some aggregated report or any other data whose
+                object structure is opaque to
+                Cayenne:<programlisting language="java">String sql = "SELECT t0.NAME, COUNT(1) FROM ARTIST t0 JOIN PAINTING t1 ON (t0.ID = t1.ARTIST_ID) "
+    + "GROUP BY t0.NAME ORDER BY COUNT(1)";
+SQLTemplate query = new SQLTemplate(Artist.class, sql);
+
+// ensure we are fetching DataRows
+query.setFetchingDataRows(true);
+
+// List of DataRow
+List&lt;DataRow> rows = context.performQuery(query);</programlisting>In
+                the example above, even though the query root is Artist. the result is a list of
+                artist names with painting counts (as mentioned before in such case "root" is only
+                used to find the DB to fetch against, but has no bearning on the result). The
+                DataRows here are the most appropriate and desired result type.</para>
+            <para>In a more advanced case you may decide to fetch a list of scalars or a list of
+                Object[] with each array entry being either an entity or a scalar. You probably
+                won't be doing this too often and it requires quite a lot of work to setup, but if
+                you want your SQLTemplate to return results similar to EJBQLQuery, it is doable
+                using SQLResult as described
+                below:<programlisting language="java">SQLTemplate query = new SQLTemplate(Painting.class, "SELECT ESTIMATED_PRICE P FROM PAINTING");
+
+// let Cayenne know that result is a scalar
+SQLResult resultDescriptor = new SQLResult();
+resultDescriptor.addColumnResult("P");
+query.setResult(resultDescriptor);
+
+// List of BigDecimals
+List&lt;BigDecimal> prices = context.performQuery(query); </programlisting><programlisting language="java">SQLTemplate query = new SQLTemplate(Artist.class, "SELECT t0.ID, t0.NAME, t0.DATE_OF_BIRTH, COUNT(t1.PAINTING_ID) C " +
+      "FROM ARTIST t0 LEFT JOIN PAINTING t1 ON (t0.ID = t1.ARTIST_ID) " +
+      "GROUP BY t0.ID, t0.NAME, t0.DATE_OF_BIRTH");
+
+// let Cayenne know that result is a mix of Artist objects and the count of their paintings
+EntityResult artistResult = new EntityResult(Artist.class);
+artistResult.addDbField(Artist.ID_PK_COLUMN, "ARTIST_ID");
+artistResult.addObjectField(Artist.NAME_PROPERTY, "NAME");
+artistResult.addObjectField(Artist.DATE_OF_BIRTH_PROPERTY, "DATE_OF_BIRTH");
+
+SQLResult resultDescriptor = new SQLResult();
+resultDescriptor.addEntityResult(artistResult);
+resultDescriptor.addColumnResult("C");
+query.setResult(resultDescriptor);
+
+// List of Object[]
+List&lt;Object[]> data = context.performQuery(query);</programlisting></para>
+            <para>Another trick related to mapping result sets is making Cayenne recognize
+                prefetched entities in the result set. This emulates "joint" prefetching of
+                SelectQuery, and is achieved by special column naming. Columns belonging to the
+                "root" entity of the query should use unqualified names corresponding to the root
+                DbEntity columns. For each related entity column names must be prefixed with
+                relationship name and a dot (e.g. "toArtist.ID"). Column naming can be controlled
+                with "#result"
+                directive:<programlisting language="java">String sql = "SELECT distinct "
+    + "#result('t1.ESTIMATED_PRICE' 'BigDecimal' '' 'paintings.ESTIMATED_PRICE'), "
+    + "#result('t1.PAINTING_TITLE' 'String' '' 'paintings.PAINTING_TITLE'), "
+    + "#result('t1.GALLERY_ID' 'int' '' 'paintings.GALLERY_ID'), "
+    + "#result('t1.ID' 'int' '' 'paintings.ID'), "
+    + "#result('NAME' 'String'), "
+    + "#result('DATE_OF_BIRTH' 'java.util.Date'), "
+    + "#result('t0.ID' 'int' '' 'ID') "
+    + "FROM ARTIST t0, PAINTING t1 "
+    + "WHERE t0.ID = t1.ARTIST_ID";
+
+SQLTemplate q = new SQLTemplate(Artist.class, sql);
+q.addPrefetch(Artist.PAINTINGS_PROPERTY)
+List&lt;Artist> objects = context.performQuery(query);</programlisting></para>
+            <para>And the final tip deals with capitalization of the DataRow keys. Queries like
+                    "<code>SELECT * FROM...</code>" and even "<code>SELECT COLUMN1, COLUMN2, ...
+                    FROM ...</code>" can sometimes result in Cayenne exceptions on attempts to
+                convert fetched DataRows to objects. Essentially any query that is not using a
+                    <code>#result</code> directive to describe the result set is prone to this
+                problem, as different databases may produce different capitalization of the
+                java.sql.ResultSet columns. </para>
+            <para>The most universal way to address this issue is to describe each column explicitly
+                in the SQLTemplate via <code>#result</code>, e.g.: "<code>SELECT #result('column1'),
+                    #result('column2'), ..</code>". However this quickly becomes impractical for
+                tables with lots of columns. For such cases Cayenne provides a shortcut based on the
+                fact that an ORM mapping usually follows some naming convention for the column
+                names. Simply put, for case-insensitive databases developers normally use either all
+                lowercase or all uppercase column names. Here is the API that takes advantage of
+                that user knowledge and forces Cayenne to follow a given naming convention for the
+                DataRow keys (this is also available as a dropdown in the
+                Modeler):<programlisting language="java">SQLTemplate query = new SQLTemplate("SELECT * FROM ARTIST");
+query.setColumnNamesCapitalization(CapsStrategy.LOWER);
+List objects = context.performQuery(query);</programlisting></para>
+            <para>or<programlisting language="java">SQLTemplate query = new SQLTemplate("SELECT * FROM ARTIST");
+query.setColumnNamesCapitalization(CapsStrategy.UPPER);
+List objects = context.performQuery(query); </programlisting></para>
+            <para>None of this affects the generated SQL, but the resulting DataRows are using
+                correct capitalization. Note that you probably shouldn't bother with this unless you
+                are getting CayenneRuntimeExceptions when fetching with SQLTemplate.</para>
+        </section>
+    </section>
\ No newline at end of file