tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Tapestry > Userguide
Date Sun, 03 Oct 2010 07:04:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/12/_/styles/combined.css?spaceKey=TAPESTRY&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/TAPESTRY/Userguide">Userguide</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~ccordenier">Christophe
Cordenier</a>
    </h4>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
            <table class="diff" cellpadding="0" cellspacing="0">
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >This persistence strategy works with
any Hibernate entity that is associated with a valid Hibernate Session by persisting only
the id of the entity. Notice that no onPassivate() method is needed; when the page renders
the entity is loaded by the id stored in the session. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h1.
Using @SessionState with entities <br> <br>{since:since=5.2}{since} <br>
<br>The default strategy for persisting Session State Objects is &quot;session&quot;.
Storing a Hibernate entity into a &lt;HttpSession&gt; is problematic because the stored
entity is detached from the Hibernate session. Similar to @Persist(&quot;entity&quot;)
you may use the &quot;entity&quot; persistence strategy to persist Hibernate entities
as SSOs: <br> <br>{code:java} <br>public class Index <br>{ <br>
 @SessionState <br>  @Property <br>  private Person person; <br> <br>
 ... <br> <br>} <br>{code} <br> <br>For this purpose you need
to set the value of the symbol &lt;HibernateSymbols.ENTITY_SESSION_STATE_PERSISTENCE_STRATEGY_ENABLED&gt;
to &lt;true&gt;: <br> <br>{code:java} <br>public class AppModule
<br>{ <br>    public static void contributeApplicationDefaults(MappedConfiguration&lt;String,
String&gt; configuration) <br>    { <br>        configuration.add(HibernateSymbols.ENTITY_SESSION_STATE_PERSISTENCE_STRATEGY_ENABLED,
&quot;true&quot;); <br>    } <br>} <br>{code} <br> <br>Alternatively
you can apply the &quot;entity&quot; persistence strategy to a single Hibernate entity:
<br> <br>{code:java} <br>public class AppModule <br>{ <br> 
  public void contributeApplicationStateManager(MappedConfiguration&lt;Class, ApplicationStateContribution&gt;
configuration) <br>    { <br>    	configuration.add(Person.class, new ApplicationStateContribution(HibernatePersistenceConstants.ENTITY));
<br>    } <br>} <br>{code} <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h1. Committing Changes <br>
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h1><a name="Userguide-Entityvalueencoding"></a>Entity value encoding</h1>

<p>Value encoders are automatically created for all mapped Hibernate entity types. This
is done by encoding the entity as it's id (coerced to a String) and decoding the entity by
looking it up in the Hibernate Session using the encoded id. Consider the following example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class ViewPerson
{
  @Property
  <span class="code-keyword">private</span> Person person;
  
  void onActivate(Person person)
  {
    <span class="code-keyword">this</span>.person = person;
  }
  
  Person onPassivate()
  {
    <span class="code-keyword">return</span> person;
  }
}</pre>
</div></div>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
&lt;html xmlns:t=<span class="code-quote">"http:<span class="code-comment">//tapestry.apache.org/schema/tapestry_5_1_0.xsd"</span>&gt;
</span>&lt;body&gt;
  The person's name is: ${person.name}
&lt;/body&gt;
&lt;/html&gt;</pre>
</div></div>

<p>Accessing the page as <b>/viewperson/152</b> would load the Person entity
with id 152 and use that as the page context.</p>

<h1><a name="Userguide-Using@PageActivationContext"></a>Using @PageActivationContext</h1>

<p>If you prefer to use annotations, you may let Tapestry generate the page activation
context handlers for you. Relying on an existing ValueEncoder for the corresponding property
you can use the @PageActivationContext annotation. The disadvantage is that you can't access
the handlers in a unit test.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class ViewPerson
{
  @Property
  @PageActivationContext
  <span class="code-keyword">private</span> Person person;
  
}</pre>
</div></div>

<h1><a name="Userguide-Using@Persistwithentities"></a>Using @Persist with
entities</h1>

<p>If you wish to persist an entity in the session, you may use the "entity" persistence
strategy:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class ViewPerson
{
  @Persist(<span class="code-quote">"entity"</span>)
  @Property
  <span class="code-keyword">private</span> Person person;
  
  void onActivate(Person person)
  {
    <span class="code-keyword">this</span>.person = person;
  }
  
}</pre>
</div></div>

<p>This persistence strategy works with any Hibernate entity that is associated with
a valid Hibernate Session by persisting only the id of the entity. Notice that no onPassivate()
method is needed; when the page renders the entity is loaded by the id stored in the session.</p>

<h1><a name="Userguide-Using@SessionStatewithentities"></a>Using @SessionState
with entities</h1>



<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Added in
5.2</b><br /></td></tr></table></div>
<div style="border-right: 20px solid #E0EFFF;border-left: 20px solid #E0EFFF;"></div>

<p>The default strategy for persisting Session State Objects is "session". Storing a
Hibernate entity into a &lt;HttpSession&gt; is problematic because the stored entity
is detached from the Hibernate session. Similar to @Persist("entity") you may use the "entity"
persistence strategy to persist Hibernate entities as SSOs:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Index
{
  @SessionState
  @Property
  <span class="code-keyword">private</span> Person person;
  
  ...
  
}
</pre>
</div></div>

<p>For this purpose you need to set the value of the symbol &lt;HibernateSymbols.ENTITY_SESSION_STATE_PERSISTENCE_STRATEGY_ENABLED&gt;
to &lt;true&gt;:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class AppModule
{
    <span class="code-keyword">public</span> <span class="code-keyword">static</span>
void contributeApplicationDefaults(MappedConfiguration&lt;<span class="code-object">String</span>,
<span class="code-object">String</span>&gt; configuration)
    {
        configuration.add(HibernateSymbols.ENTITY_SESSION_STATE_PERSISTENCE_STRATEGY_ENABLED,
<span class="code-quote">"<span class="code-keyword">true</span>"</span>);
    }
}
</pre>
</div></div>

<p>Alternatively you can apply the "entity" persistence strategy to a single Hibernate
entity:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class AppModule
{
    <span class="code-keyword">public</span> void contributeApplicationStateManager(MappedConfiguration&lt;<span
class="code-object">Class</span>, ApplicationStateContribution&gt; configuration)
    {
    	configuration.add(Person.class, <span class="code-keyword">new</span> ApplicationStateContribution(HibernatePersistenceConstants.ENTITY));
    }
}
</pre>
</div></div>

<h1><a name="Userguide-CommittingChanges"></a>Committing Changes</h1>

<p>All Hibernate operations occur in a transaction, but that transaction is aborted
at the end of each request; thus any changes you make will be <em>lost</em> unless
the transaction is committed.</p>

<p>The correct way to commit the transaction is via the @CommitAfter annotation:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class EditPerson
{
  @Persist(<span class="code-quote">"entity"</span>)
  @Property
  <span class="code-keyword">private</span> Person person;

  @InjectPage
  <span class="code-keyword">private</span> PersonIndex personIndex;

  void onActivate(Person person)
  {
    <span class="code-keyword">this</span>.person = person;
  }

  <span class="code-object">Object</span> onPassivate() { <span class="code-keyword">return</span>
person; }

  @CommitAfter
  <span class="code-object">Object</span> onSuccess()
  {
    <span class="code-keyword">return</span> personIndex;
  }
}</pre>
</div></div>

<p>In this example, the Person object may be updated by a form; the form's success event
handler method, onSuccess() has the @CommitAfter annotation.</p>

<p>Behind the scenes, the @CommitAfter annotation causes the <span class="error">&#91;HibernateSessionManager|../apidocs/org/apache/tapestry5/hibernate/HibernateSessionManager.html&#93;</span>'s
commit() method to be executed before the method returns.</p>

<p>The transaction will be committed when the method completes normally.</p>

<p>The transaction will be <em>aborted</em> if the method throws a RuntimeException.</p>

<p>The transaction will be <b>committed</b> if the method throws a <em>checked</em>
exception (one listed in the throws clause of the method).</p>

<h1><a name="Userguide-ManagingTransactionsusingDAOs"></a>Managing Transactions
using DAOs</h1>

<p>As your application grows, you will likely create a Data Access Object layer between
your pages and the Hibernate APIs.</p>

<p>The @CommitAfter annotation can be useful there as well.</p>

<p>You may use @CommitAfter on method of your service interface, then use a decorator
to provide the transaction management logic.</p>

<p>First definine your DAO's service interface:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-keyword">interface</span>
PersonDAO
{
  Person findByName(<span class="code-object">String</span> name);

  @CommitAfter
  void add(Person newPerson);

  @CommitAfter
  void update(Person person);

  @CommitAfter
  void delete(Person person);
}</pre>
</div></div>

<p>Next, define your service in your application's Module class:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class AppModule
{
   <span class="code-keyword">public</span> <span class="code-keyword">static</span>
void bind(ServiceBinder binder)
   {
      binder.bind(PersonDAO.class, PersonDAOImpl.class);
   }
}</pre>
</div></div>

<p>Finally, you should use the HibernateTransactionAdvisor to add transaction advice:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    @Match(<span class="code-quote">"*DAO"</span>)
    <span class="code-keyword">public</span> <span class="code-keyword">static</span>
void adviseTransactions(HibernateTransactionAdvisor advisor, MethodAdviceReceiver receiver)
    {
        advisor.addTransactionCommitAdvice(receiver);
    }</pre>
</div></div>

<p>This advice method is configured to match against any service whose id ends with
"DAO", such as "PersonDAO".</p>

<p>The advisor scans the service interface and identifies any methods with the @CommitAfter
annotation.</p>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/TAPESTRY/Userguide">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=23338473&revisedVersion=3&originalVersion=2">View
Changes</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message