[hibernate-commits] Hibernate SVN: r19964 - core/trunk/documentation/manual/src/main/docbook/en-US/content.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Fri Jul 16 16:53:11 EDT 2010
Author: hardy.ferentschik
Date: 2010-07-16 16:53:11 -0400 (Fri, 16 Jul 2010)
New Revision: 19964
Modified:
core/trunk/documentation/manual/src/main/docbook/en-US/content/query_sql.xml
Log:
HHH-5389
Modified: core/trunk/documentation/manual/src/main/docbook/en-US/content/query_sql.xml
===================================================================
--- core/trunk/documentation/manual/src/main/docbook/en-US/content/query_sql.xml 2010-07-16 19:46:12 UTC (rev 19963)
+++ core/trunk/documentation/manual/src/main/docbook/en-US/content/query_sql.xml 2010-07-16 20:53:11 UTC (rev 19964)
@@ -928,15 +928,42 @@
<para>Hibernate3 can use custom SQL for create, update, and delete
operations. The SQL can be overridden at the statement level or
inidividual column level. This section describes statement overrides. For
- columns, see <xref linkend="mapping-column-read-and-write" />.</para>
+ columns, see <xref linkend="mapping-column-read-and-write" />. <xref
+ linkend="example-custom-crdu-via-annotations" /> shows how to define
+ custom SQL operatons using annotations.</para>
- <para>The class and collection persisters in Hibernate already contain a
- set of configuration time generated strings (insertsql, deletesql,
- updatesql etc.). The mapping tags <literal><sql-insert></literal>,
- <literal><sql-delete></literal>, and
- <literal><sql-update></literal> override these strings:</para>
+ <example id="example-custom-crdu-via-annotations">
+ <title>Custom CRUD via annotations</title>
- <programlisting role="XML"><class name="Person">
+ <programlisting language="JAVA" role="JAVA">@Entity
+ at Table(name="CHAOS")
+ at SQLInsert( sql="INSERT INTO CHAOS(size, name, nickname, id) VALUES(?,upper(?),?,?)")
+ at SQLUpdate( sql="UPDATE CHAOS SET size = ?, name = upper(?), nickname = ? WHERE id = ?")
+ at SQLDelete( sql="DELETE CHAOS WHERE id = ?")
+ at SQLDeleteAll( sql="DELETE CHAOS")
+ at Loader(namedQuery = "chaos")
+ at NamedNativeQuery(name="chaos", query="select id, size, name, lower( nickname ) as nickname from CHAOS where id= ?", resultClass = Chaos.class)
+public class Chaos {
+ @Id
+ private Long id;
+ private Long size;
+ private String name;
+ private String nickname;</programlisting>
+ </example>
+
+ <para><literal>@SQLInsert</literal>, <literal>@SQLUpdate</literal>,
+ <literal>@SQLDelete</literal>, <literal>@SQLDeleteAll</literal>
+ respectively override the INSERT, UPDATE, DELETE, and DELETE all
+ statement. The same can be achieved using Hibernate mapping files and the
+ <literal><sql-insert></literal>,
+ <literal><sql-update></literal> and
+ <literal><sql-delete></literal> nodes. This can be seen in <xref
+ linkend="example-custom-crdu-via-xml" />.</para>
+
+ <example id="example-custom-crdu-via-xml">
+ <title>Custom CRUD XML</title>
+
+ <programlisting role="XML"><class name="Person">
<id name="id">
<generator class="increment"/>
</id>
@@ -945,41 +972,100 @@
<sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update>
<sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete>
</class></programlisting>
+ </example>
- <para>The SQL is directly executed in your database, so you can use any
- dialect you like. This will reduce the portability of your mapping if you
- use database specific SQL.</para>
+ <para>If you expect to call a store procedure, be sure to set the
+ <literal>callable</literal> attribute to <constant>true</constant>. In
+ annotations as well as in xml. </para>
- <para>Stored procedures are supported if the <literal>callable</literal>
- attribute is set:</para>
+ <para>To check that the execution happens correctly, Hibernate allows you
+ to define one of those three strategies:</para>
- <programlisting role="XML"><class name="Person">
- <id name="id">
- <generator class="increment"/>
- </id>
- <property name="name" not-null="true"/>
- <sql-insert callable="true">{call createPerson (?, ?)}</sql-insert>
- <sql-delete callable="true">{? = call deletePerson (?)}</sql-delete>
- <sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update>
-</class></programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>none: no check is performed: the store procedure is expected to
+ fail upon issues</para>
+ </listitem>
- <para>The order of the positional parameters is vital, as they must be in
- the same sequence as Hibernate expects them.</para>
+ <listitem>
+ <para>count: use of rowcount to check that the update is
+ successful</para>
+ </listitem>
- <para>You can view the expected order by enabling debug logging for the
- <literal>org.hibernate.persister.entity</literal> level. With this level
- enabled, Hibernate will print out the static SQL that is used to create,
- update, delete etc. entities. To view the expected sequence, do not
- include your custom SQL in the mapping files, as this will override the
- Hibernate generated static SQL.</para>
+ <listitem>
+ <para>param: like COUNT but using an output parameter rather that the
+ standard mechanism</para>
+ </listitem>
+ </itemizedlist>
- <para>The stored procedures are in most cases required to return the
- number of rows inserted, updated and deleted, as Hibernate has some
- runtime checks for the success of the statement. Hibernate always
+ <para>To define the result check style, use the <literal>check</literal>
+ parameter which is again available in annoations as well as in xml.</para>
+
+ <para>You can use the exact same set of annotations respectively xml nodes
+ to override the collection related statements -see <xref
+ linkend="example-overriding-sql-collections-annotations" />.</para>
+
+ <example id="example-overriding-sql-collections-annotations">
+ <title>Overriding SQL statements for collections using
+ annotations</title>
+
+ <programlisting language="JAVA" role="JAVA">@OneToMany
+ at JoinColumn(name="chaos_fk")
+ at SQLInsert( sql="UPDATE CASIMIR_PARTICULE SET chaos_fk = ? where id = ?")
+ at SQLDelete( sql="UPDATE CASIMIR_PARTICULE SET chaos_fk = null where id = ?")
+private Set<CasimirParticle> particles = new HashSet<CasimirParticle>();</programlisting>
+ </example>
+
+ <tip>
+ <para>The parameter order is important and is defined by the order
+ Hibernate handles properties. You can see the expected order by enabling
+ debug logging for the <literal>org.hibernate.persister.entity</literal>
+ level. With this level enabled Hibernate will print out the static SQL
+ that is used to create, update, delete etc. entities. (To see the
+ expected sequence, remember to not include your custom SQL through
+ annotations or mapping files as that will override the Hibernate
+ generated static sql)</para>
+ </tip>
+
+ <para>Overriding SQL statements for secondary tables is also possible
+ using <literal>@org.hibernate.annotations.Table</literal> and either (or
+ all) attributes <literal>sqlInsert</literal>,
+ <literal>sqlUpdate</literal>, <literal>sqlDelete</literal>:</para>
+
+ <example>
+ <title>Overriding SQL statements for secondary tables</title>
+
+ <programlisting language="JAVA" role="JAVA">@Entity
+ at SecondaryTables({
+ @SecondaryTable(name = "`Cat nbr1`"),
+ @SecondaryTable(name = "Cat2"})
+ at org.hibernate.annotations.Tables( {
+ @Table(appliesTo = "Cat", comment = "My cat table" ),
+ @Table(appliesTo = "Cat2", foreignKey = @ForeignKey(name="FK_CAT2_CAT"), fetch = FetchMode.SELECT,
+ sqlInsert=@SQLInsert(sql="insert into Cat2(storyPart2, id) values(upper(?), ?)") )
+} )
+public class Cat implements Serializable {</programlisting>
+ </example>
+
+ <para>The previous example also shows that you can give a comment to a
+ given table (primary or secondary): This comment will be used for DDL
+ generation.</para>
+
+ <tip>
+ <para>The SQL is directly executed in your database, so you can use any
+ dialect you like. This will, however, reduce the portability of your
+ mapping if you use database specific SQL.</para>
+ </tip>
+
+ <para>Last but not least, stored procedures are in most cases required to
+ return the number of rows inserted, updated and deleted. Hibernate always
registers the first statement parameter as a numeric output parameter for
the CUD operations:</para>
- <programlisting>CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2)
+ <example>
+ <title>Stored procedures and their return value</title>
+
+ <programlisting>CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2)
RETURN NUMBER IS
BEGIN
@@ -992,6 +1078,7 @@
return SQL%ROWCOUNT;
END updatePerson;</programlisting>
+ </example>
</section>
<section id="querysql-load">
@@ -1052,5 +1139,9 @@
ON pers.ID = emp.PERSON_ID
WHERE ID=?
</sql-query></programlisting>
+
+ <para>The annotation equivalent <literal><loader></literal> is the
+ @Loader annotation as seen in <xref
+ linkend="example-custom-crdu-via-annotations" />.</para>
</section>
</chapter>
More information about the hibernate-commits
mailing list