You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by bu...@apache.org on 2015/06/27 23:21:05 UTC

svn commit: r956226 [34/34] - in /websites/production/tapestry/content: ./ 2010/10/11/ 2010/10/31/ 2010/11/18/ 2010/11/19/ 2010/12/16/ 2010/12/17/ 2011/01/10/ 2011/03/29/ 2011/06/13/ 2011/06/24/ 2011/06/29/ 2011/07/29/ 2011/08/16/ 2011/08/27/ 2011/10/3...

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 Jun 27 21:21:02 2015
@@ -27,16 +27,6 @@
   </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css">
 
-    <link href='/resources/highlighter/styles/shCoreCXF.css' rel='stylesheet' type='text/css' />
-  <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' type='text/css' />
-  <script src='/resources/highlighter/scripts/shCore.js' type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushJava.js' type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushXml.js' type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushPlain.js' type='text/javascript'></script>
-  <script type="text/javascript">
-  SyntaxHighlighter.defaults['toolbar'] = false;
-  SyntaxHighlighter.all();
-  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -55,7 +45,7 @@
   <input type="submit" value="Search">
 </form>
 
-</div><div class="emblem" style="float:left"><p><a shape="rect" href="index.html"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Using Tapestry With Hibernate</h1></div></div>
+</div><div class="emblem" style="float:left"><p><a shape="rect" href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Using Tapestry With Hibernate</h1></div></div>
 <div class="clearer"></div>
 </div>
 
@@ -76,7 +66,7 @@ table.ScrollbarTable td.ScrollbarNextNam
 table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}
 
 /*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="using-beaneditform-to-create-user-forms.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="using-beaneditform-to-create-user-forms.html">Using BeanEditForm To Create User Forms</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="tapestry-tutorial.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="tapestry-tutorial.html">Tapestry Tutorial</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;</td></tr></table></div><p>So, you fill in all the fields, submit the form (without validation erro
 rs) and voila: you get back the same form, blanked out. What happened, and where did the data go?</p><p>What happened is that we haven't told Tapestry what to do after the form is successfully submitted (by successful, we mean, with no validation errors). Tapestry's default behavior is to redisplay the active page, and that occurs in a new request, with a new instance of the Address object (because the address field is not a peristent field).</p><p>Well, since we're creating objects, we might as well store them somewhere ... in a database. We're going to quickly integrate Tapestry with <a shape="rect" class="external-link" href="http://hibernate.org" >Hibernate</a> as the object/relational mapping layer, and ultimately store our data inside a <a shape="rect" class="external-link" href="http://www.hsqldb.org/" >HyperSQL</a> (HSQLDB) database. HSQLDB is an embedded database engine and requires no installation &#8211; it will be pulled down as a dependency by Maven.</p><h2 id="UsingTap
 estryWithHibernate-Re-configuringtheProject">Re-configuring the Project</h2><p>We're going to bootstrap this project from a simple Tapestry project to one that uses Hibernate and HSQLDB.</p><h3 id="UsingTapestryWithHibernate-UpdatingtheDependencies">Updating the Dependencies</h3><p>First, we must update the POM to list a new set of dependencies, that includes Hibernate, the Tapestry/Hibernate integration library, and the HSQLDB JDBC driver:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>src/pom.xml (partial)</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[    &lt;dependencies&gt;
+<script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[    &lt;dependencies&gt;
 
         &lt;dependency&gt;
             &lt;groupId&gt;org.apache.tapestry&lt;/groupId&gt;
@@ -93,7 +83,7 @@ table.ScrollbarTable td.ScrollbarNextIco
     &lt;/dependencies&gt;
 ]]></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 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
+<script class="brush: xml; gutter: false; theme: Default" 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;
 &lt;hibernate-configuration&gt;
@@ -110,7 +100,7 @@ table.ScrollbarTable td.ScrollbarNextIco
 &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 ("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;
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[package com.example.tutorial.entities;
 
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
@@ -157,7 +147,7 @@ public class Address
 }
 ]]></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><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;
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[package com.example.tutorial.pages.address;
 
 import com.example.tutorial.entities.Address;
 import com.example.tutorial.pages.Index;
@@ -187,12 +177,12 @@ 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 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="using-tapestry-with-hibernate.data/index-grid-v1.png" data-image-src="/
 confluence/download/attachments/23340507/index-grid-v1.png?version=4&amp;modificationDate=1418482289000&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="border-bottom-width: 1px;"><b>src/main/webapp/Index.tml (partial)</b></div><div class="c
 odeContent panelContent pdl">
-<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[  &lt;t:grid source=&quot;addresses&quot;
+</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><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-content-image-border" src="using-tapestry-with-hibe
 rnate.data/index-grid-v1.png" data-image-src="/confluence/download/attachments/23340507/index-grid-v1.png?version=4&amp;modificationDate=1418482289000&amp;api=v2" data-unresolved-comment-count="0" data-linked-resource-id="23527751" data-linked-resource-version="4" data-linked-resource-type="attachment" data-linked-resource-default-alias="index-grid-v1.png" data-base-url="https://cwiki.apache.org/confluence" data-linked-resource-content-type="image/png" data-linked-resource-container-id="23340507" data-linked-resource-container-version="33"></span></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 in
 to 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="border-bottom-width: 1px;"><b>src/main/webapp/Index.tml (partial)</b></div><div class="codeContent panelContent pdl">
+<script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  &lt;t:grid source=&quot;addresses&quot;
          include=&quot;honorific,firstName,lastName,street1,city,state,zip,phone&quot;/&gt;
 ]]></script>
 </div></div><p>Note that the Grid component accepts many of the same parameters that we used with the BeanEditForm. Here we use the include parameter to specify the properties to show, and in what order.</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;
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[package com.example.tutorial.pages;
 import java.util.List;
 import org.apache.tapestry5.ioc.annotations.Inject;
 import org.hibernate.Session;

Modified: websites/production/tapestry/content/version-numbers.html
==============================================================================
--- websites/production/tapestry/content/version-numbers.html (original)
+++ websites/production/tapestry/content/version-numbers.html Sat Jun 27 21:21:02 2015
@@ -45,7 +45,7 @@
   <input type="submit" value="Search">
 </form>
 
-</div><div class="emblem" style="float:left"><p><a shape="rect" href="index.html"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Version Numbers</h1></div></div>
+</div><div class="emblem" style="float:left"><p><a shape="rect" href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Version Numbers</h1></div></div>
 <div class="clearer"></div>
 </div>
 
@@ -59,15 +59,8 @@
 <div id="content">
 <div id="ConfluenceContent">
 
-    <div class="aui-message hint shadowed information-macro">
-                    <p class="title">Added in 5.3</p>
-                            <span class="aui-icon icon-hint">Icon</span>
-                <div class="message-content">
-                            
-
-                    </div>
-    </div>
-
+<div class="confluence-information-macro confluence-information-macro-information"><p class="title">Added in 5.3</p><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
+</div></div>
 <div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;">
 
 <p>Tapestry version numbering was change starting in release 5.3.  Tapestry 5.2 and earlier used a different numbering scheme whose primary failing was that, from the version number, it was not obvious what the <em>stability</em> of the version was.</p>

Modified: websites/production/tapestry/content/whatistapestry.html
==============================================================================
--- websites/production/tapestry/content/whatistapestry.html (original)
+++ websites/production/tapestry/content/whatistapestry.html Sat Jun 27 21:21:02 2015
@@ -45,7 +45,7 @@
   <input type="submit" value="Search">
 </form>
 
-</div><div class="emblem" style="float:left"><p><a shape="rect" href="index.html"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">whatIsTapestry</h1></div></div>
+</div><div class="emblem" style="float:left"><p><a shape="rect" href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">whatIsTapestry</h1></div></div>
 <div class="clearer"></div>
 </div>