Author: buildbot
Date: Sat Dec 13 14:19:35 2014
New Revision: 932579

Log:
Production update by buildbot for tapestry

Modified:
    websites/production/tapestry/content/cache/main.pageCache
    
websites/production/tapestry/content/using-tapestry-with-hibernate.data/index-grid-v1.png
    websites/production/tapestry/content/using-tapestry-with-hibernate.html

Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.

Modified: 
websites/production/tapestry/content/using-tapestry-with-hibernate.data/index-grid-v1.png
==============================================================================
Binary files - no diff available.

Modified: 
websites/production/tapestry/content/using-tapestry-with-hibernate.html
==============================================================================
--- websites/production/tapestry/content/using-tapestry-with-hibernate.html 
(original)
+++ websites/production/tapestry/content/using-tapestry-with-hibernate.html Sat 
Dec 13 14:19:35 2014
@@ -84,14 +84,14 @@ table.ScrollbarTable td.ScrollbarNextIco
         </dependency>
 
         <dependency>
-            <groupId>hsqldb</groupId>
+            <groupId>org.hsqldb</groupId>
             <artifactId>hsqldb</artifactId>
-            <version>1.8.0.7</version>
+            <version>2.3.2</version>
         </dependency>
         ...
     </dependencies>
 ]]></script>
-</div></div><p>The tapestry-hibernate library includes, as transitive 
dependencies, Hibernate and tapestry-core. This means that you can simply 
replace "tapestry-core" with "tapestry-hibernate" inside the &lt;artifactId&gt; 
element.</p><p>After changing the POM and saving, Maven should automatically 
download the new dependencies.</p><h3 
id="UsingTapestryWithHibernate-HibernateConfiguration">Hibernate 
Configuration</h3><p>Hibernate has a master configuration file used to store 
connection and other data.</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>src/main/resources/hibernate.cfg.xml</b></div><div class="codeContent 
panelContent pdl">
+</div></div><p>The tapestry-hibernate library includes, as transitive 
dependencies, Hibernate and tapestry-core. This means that you can simply 
replace "tapestry-core" with "tapestry-hibernate" inside the &lt;artifactId&gt; 
element.</p><p>After changing the POM and saving, Maven should automatically 
download the JARs for the new dependencies.</p><h3 
id="UsingTapestryWithHibernate-HibernateConfiguration">Hibernate 
Configuration</h3><p>Hibernate needs a master configuration file, 
hibernate.cfg.xml, used to store connection and other data. Create this in your 
src/main/resources folder:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>src/main/resources/hibernate.cfg.xml</b></div><div class="codeContent 
panelContent pdl">
 <script class="theme: Default; brush: xml; gutter: false" 
type="syntaxhighlighter"><![CDATA[&lt;!DOCTYPE hibernate-configuration PUBLIC
         &quot;-//Hibernate/Hibernate Configuration DTD 3.0//EN&quot;
         
&quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot;&gt;
@@ -108,7 +108,7 @@ table.ScrollbarTable td.ScrollbarNextIco
     &lt;/session-factory&gt;
 &lt;/hibernate-configuration&gt;
 ]]></script>
-</div></div><p>Most of the configuration is to identify the JDBC driver and 
connection URL.</p><p>Note the connection URL. We are instructing HSQLDB to 
store its database files within our project's target directory. We are also 
instructing HSQLDB to flush any data to these files at shutdown. This means 
that data will persist across different invocations of this project, but if the 
target directory is destroyed (e.g., via "mvn clean"), then all the database 
contents will be lost.</p><p>In addition, we are configuring Hibernate to 
<em>update</em> the database schema; when Hibernate initializes it will create 
or even modify tables to match the entities. Finally, we are configuring 
Hibernate to output any SQL it executes, which is very useful when initially 
building an application.</p><p>But what entities? Normally, the available 
entities are listed inside hibernate.cfg.xml, but that's not necessary with 
Tapestry; in another example of convention over configuration, Tapestry locates 
all
  entity classes inside the entities package and adds them to the 
configuration. Currently, that is just the Address entity.</p><h2 
id="UsingTapestryWithHibernate-AddingHibernateAnnotations">Adding Hibernate 
Annotations</h2><p>For an entity class to be used with Hibernate, some 
Hibernate annotations must be added to the class.</p><p>Below is the updated 
Address class, with the Hibernate annotations (as well as the Tapestry 
ones).</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>src/main/java/com/example/tutorial/entities/Address.java</b></div><div 
class="codeContent panelContent pdl">
+</div></div><p>Most of the configuration is to identify the JDBC driver and 
connection URL.</p><p>Note the connection URL. We are instructing HSQLDB to 
store its database files within our project's target directory. We are also 
instructing HSQLDB to flush any data to these files at shutdown. This means 
that data will persist across different invocations of this project, but if the 
target directory is destroyed (e.g., via "mvn clean"), then all the database 
contents will be lost.</p><p>In addition, we are configuring Hibernate to 
<em>update</em> the database schema; when Hibernate initializes it will create 
or even modify tables to match the entities. Finally, we are configuring 
Hibernate to output any SQL it executes, which is very useful when initially 
building an application.</p><p>But what entities? Normally, the available 
entities are listed inside hibernate.cfg.xml, but that's not necessary with 
Tapestry; in another example of convention over configuration, Tapestry locates 
all
  entity classes inside the entities package ("com.example.tutorial.entities" 
in our case) and adds them to the configuration. Currently, that is just the 
Address entity.</p><h2 
id="UsingTapestryWithHibernate-AddingHibernateAnnotations">Adding Hibernate 
Annotations</h2><p>For an entity class to be used with Hibernate, some 
Hibernate annotations must be added to the class.</p><p>Below is the updated 
Address class, with the Hibernate annotations (as well as the Tapestry 
ones).</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>src/main/java/com/example/tutorial/entities/Address.java</b></div><div 
class="codeContent panelContent pdl">
 <script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[package com.example.tutorial.entities;
 
 import javax.persistence.Entity;
@@ -155,7 +155,7 @@ public class Address
   public String phone;
 }
 ]]></script>
-</div></div><p>The Tapestry annotations, @NonVisual and @Validate, may be 
placed on the setter or getter method or on the field (as we have done here). 
As with the Hibernate annotations, putting the annotation on the field requires 
that the field name match the corresponding property 
name.</p><ul><li><strong>@NonVisual</strong> &#8211; indicates a field, such as 
a primary key, that should not be made visible to the 
user.</li><li><strong>@Validate</strong> &#8211; identifies the validations 
associated with a field.</li></ul><h2 
id="UsingTapestryWithHibernate-UpdatingtheDatabase">Updating the 
Database</h2><p>So we have a database up and running, and Hibernate is 
configured to connect to it. Let's make use of that to store our Address object 
in the database.</p><p>What we need is to provide some code to be executed when 
the form is submitted. When a Tapestry form is submitted, there is a whole 
series of events that get fired. The event we are interested in is the 
"success" event, which
  comes late in the process, after all the values have been pulled out of the 
request and applied to the page properties, and after all server-side 
validations have occured.</p><p>The success event is only fired if there are no 
validation errors.</p><p>Our event handler must do two things:</p><ul><li>Use 
the Hibernate Session object to persist the new Address object.</li><li>Commit 
the transaction to force the data to be written to the database.</li></ul><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 
1px;"><b>src/main/java/com/example/tutorial/pages/address/CreateAddress.java</b></div><div
 class="codeContent panelContent pdl">
+</div></div><p>The Tapestry annotations, @NonVisual and @Validate, may be 
placed on the setter or getter method or on the field (as we have done here). 
As with the Hibernate annotations, putting the annotation on the field requires 
that the field name match the corresponding property 
name.</p><ul><li><strong>@NonVisual</strong> &#8211; indicates a field, such as 
a primary key, that should not be made visible to the 
user.</li><li><strong>@Validate</strong> &#8211; identifies the validations 
associated with a field.</li></ul><p>At this point you should stop and restart 
your application.</p><h2 
id="UsingTapestryWithHibernate-UpdatingtheDatabase">Updating the 
Database</h2><p>So we have a database set up, and Hibernate is configured to 
connect to it. Let's make use of that to store our Address object in the 
database.</p><p>What we need is to provide some code to be executed when the 
form is submitted. When a Tapestry form is submitted, there is a whole series 
of events that get fired. Th
 e event we are interested in is the "success" event, which comes late in the 
process, after all the values have been pulled out of the request and applied 
to the page properties, and after all server-side validations have 
occurred.</p><p>The success event is only fired if there are no validation 
errors.</p><p>Our event handler must do two things:</p><ul><li>Use the 
Hibernate Session object to persist the new Address object.</li><li>Commit the 
transaction to force the data to be written to the database.</li></ul><p>Let's 
update our CreateAddress.java class:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 
1px;"><b>src/main/java/com/example/tutorial/pages/address/CreateAddress.java</b></div><div
 class="codeContent panelContent pdl">
 <script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[package com.example.tutorial.pages.address;
 
 import com.example.tutorial.entities.Address;
@@ -186,17 +186,25 @@ public class CreateAddress
     }
 }
 ]]></script>
-</div></div><p>The <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html";>Inject</a>
 annotation tells Tapestry to inject a service into the annotated field; 
Tapestry includes a sophisticated Inversion of Control container (similar in 
many ways to Spring) that is very good at locating available services by type, 
rather than by a string id. In any case, the Hibernate Session object is 
exposed as a Tapestry IoC service, ready to be injected (this is one of the 
things provided by the tapestry-hibernate module).</p><p>Tapestry automatically 
starts a transaction as necessary; however that transaction will be 
<em>aborted</em> at the end of the request. If we make changes to persistent 
objects, such as adding a new Address object, then it is necessary to commit 
the transaction.</p><p>The <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/hibernate/annota
 tions/CommitAfter.html">CommitAfter</a> annotation can be applied to any 
component method; if the method completes normally, the transaction will be 
committed (and a new transaction started to replace the committed 
transaction).</p><p>After persisting the new address, we return to the main 
Index page of the application.</p><p><em>Note: In real applications, it is rare 
to have pages and components directly use the Hibernate Session. It is 
generally a better approach to define your own Data Access Object layer to 
perform common update operations and queries.</em></p><h2 
id="UsingTapestryWithHibernate-ShowingAddresses">Showing Addresses</h2><p>As a 
little preview of what's next, let's display all the Addresses entered by the 
user on the Index page of the application. After you enter a few names, it will 
look something like:</p><p><img class="confluence-embedded-image 
confluence-content-image-border" 
src="https://cwiki.apache.org/confluence/download/attachments/23340507/index-grid-v1.pn
 g?version=1&amp;modificationDate=1286814603000&amp;api=v2" 
data-image-src="/confluence/download/attachments/23340507/index-grid-v1.png?version=1&amp;modificationDate=1286814603000&amp;api=v2"></p><h2
 id="UsingTapestryWithHibernate-AddingtheGridtotheIndexpage">Adding the Grid to 
the Index page</h2><p>So, how is this implemented? Primarily, its accomplished 
by the <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Grid.html";>Grid</a>
 component.</p><p>The Grid component is based on the same concepts as the 
BeanEditForm component; it can pull apart a bean into columns. The columns are 
sortable, and when there are more entries than will fit on a single page, page 
navigation is automatically added.</p><p>A minimal Grid is very easy to add to 
the template:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>src/main/webapp/Index.tml 
 (partial)</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: xml; gutter: false" 
type="syntaxhighlighter"><![CDATA[  &lt;t:grid source=&quot;addresses&quot;/&gt;
-]]></script>
-</div></div><p>And all we have to do is supply the addresses property in the 
Java code:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>src/main/java/com/example/tutorial/pages/Index.java 
(partial)</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[    @Inject
+</div></div><p>The <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html";>Inject</a>
 annotation tells Tapestry to inject a service into the annotated field; 
Tapestry includes a sophisticated Inversion of Control container (similar in 
many ways to Spring) that is very good at locating available services by type, 
rather than by a string id. In any case, the Hibernate Session object is 
exposed as a Tapestry IoC service, ready to be injected (this is one of the 
things provided by the tapestry-hibernate module).</p><p>Tapestry automatically 
starts a transaction as necessary; however that transaction will be 
<em>aborted</em> at the end of the request by default. If we make changes to 
persistent objects, such as adding a new Address object, then it is necessary 
to commit the transaction.</p><p>The <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/hiber
 nate/annotations/CommitAfter.html">CommitAfter</a> annotation can be applied 
to any component method; if the method completes normally, the transaction will 
be committed (and a new transaction started to replace the committed 
transaction).</p><p>After persisting the new address, we return to the main 
Index page of the application.</p><p><em>Note: In real applications, it is rare 
to have pages and components directly use the Hibernate Session. It is 
generally a better approach to define your own Data Access Object layer to 
perform common update operations and queries.</em></p><h2 
id="UsingTapestryWithHibernate-ShowingAddresses">Showing Addresses</h2><p>As a 
little preview of what's next, let's display all the Addresses entered by the 
user on the Index page of the application. After you enter a few names, it will 
look something like:</p><p><img class="confluence-embedded-image 
confluence-content-image-border" 
src="https://cwiki.apache.org/confluence/download/attachments/23340507/index
 -grid-v1.png?version=3&amp;modificationDate=1418479523098&amp;api=v2" 
data-image-src="/confluence/download/attachments/23340507/index-grid-v1.png?version=3&amp;modificationDate=1418479523098&amp;api=v2"></p><h2
 id="UsingTapestryWithHibernate-AddingtheGridtotheIndexpage">Adding the Grid to 
the Index page</h2><p>So, how is this implemented? Primarily, its accomplished 
by the <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Grid.html";>Grid</a>
 component.</p><p>The Grid component is based on the same concepts as the 
BeanEditForm component; it can pull apart a bean into columns. The columns are 
sortable, and when there are more entries than will fit on a single page, page 
navigation is automatically added.</p><p>A minimal Grid is very easy to add to 
the template. Just add this near the bottom of Index.tml:</p><div class="code 
panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="b
 order-bottom-width: 1px;"><b>src/main/webapp/Index.tml (partial)</b></div><div 
class="codeContent panelContent pdl">
+<script class="theme: Default; brush: xml; gutter: false" 
type="syntaxhighlighter"><![CDATA[  &lt;t:grid source=&quot;addresses&quot;
+         
reorder=&quot;honorific,firstName,lastName,street1,street2,city,state,zip,email,phone&quot;/&gt;
+]]></script>
+</div></div><p>Note that the Grid component accepts the same "reorder" 
parameter that we used with the BeanEditForm.</p><p>Now all we have to do is 
supply the addresses property in the Java code. Here's how Index.java should 
look now:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>src/main/java/com/example/tutorial/pages/Index.java</b></div><div 
class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[package com.example.tutorial.pages;
+import java.util.List;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.hibernate.Session;
+import com.example.tutorial.entities.Address;
+public class Index
+{
+    @Inject
     private Session session;
-
     public List&lt;Address&gt; getAddresses()
     {
         return session.createCriteria(Address.class).list();
     }
+}
 ]]></script>
 </div></div><p>Here, we're using the Hibernate Session object to find all 
Address objects in the database. Any sorting that takes place will be done in 
memory. This is fine for now (with only a handful of Address objects in the 
database). Later we'll see how to optimize this for very large result 
sets.</p><h2 id="UsingTapestryWithHibernate-What'sNext?">What's Next?</h2><p>We 
have lots more to talk about: more components, more customizations, built-in 
Ajax support, more common design and implementation patterns, and even writing 
your own components (which is easy!).</p><p>Check out the many Tapestry 
resources available on the <a shape="rect" href="documentation.html">Tapestry 5 
Documentation page</a> page, including the <a shape="rect" 
href="getting-started.html">Getting Started</a> and <a shape="rect" 
href="frequently-asked-questions.html">FAQ</a> pages and the <a shape="rect" 
href="cookbook.html">Cookbook Recipies</a>. Be sure to peruse the <a 
shape="rect" href="user-guide.html">Us
 er Guide</a>, which provides comprehensive details on nearly every Tapestry 
topic.</p><style type="text/css">/*<![CDATA[*/
 table.ScrollbarTable  {border: none;padding: 3px;width: 100%;padding: 
3px;margin: 0px;background-color: #f0f0f0}


Reply via email to