<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:thr="http://purl.org/syndication/thread/1.0">
  <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-4.html" />
  <link rel="self" type="application/atom+xml" href="http://www.insideria.com/atom.xml" />
  <id>tag:www.insideria.com,2009://34/tag:www.insideria.com,2008://34.23198-</id>
  <updated>2009-11-05T20:17:24Z</updated>
  <title>Comments for Anatomy of an Enterprise Flex RIA Part 10: DTOs or VOs (http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-4.html)</title>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>
  <entry>
    <id>tag:www.insideria.com,2008://34.23198</id>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-4.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://blogs.oreilly.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=34/entry_id=23198" title="Anatomy of an Enterprise Flex RIA Part 10: DTOs or VOs" />
    <published>2008-03-24T14:06:19Z</published>
    <updated>2008-10-01T01:25:00Z</updated>
    <title>Anatomy of an Enterprise Flex RIA Part 10: DTOs or VOs</title>
    <summary>Last week we looked at the Actionscript and Java code for the persistent entities in our application.  In this week&#8217;s installment of Anatomy of an Enterprise Flex RIA, we&apos;re going to look at the Java code for the service layer in our application and introduce the concept of the session bean from EJB 3.0.  Follow along every Monday with our development tutorial. </summary>
    <author>
      <name>Tony Hillerson</name>
      
    </author>
    
    <category term="Features" />
    
    <content type="html" xml:lang="en" xml:base="http://www.insideria.com/">
      <![CDATA[
<div class="ap_r" style="margin: 16px;"><a href="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex/riaseries_part10.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex/riaseries_part10.jpg" alt="riaseries_part10.jpg" title="Click to enlarge" width="148"/></a></div>

<p><a href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-3.html" target="_blank">Last installment</a> we looked at the Actionscript and Java code for the persistent entities in our application. This week we'll look at the code that will create, update, and delete those entities: the service layer.</p>

<strong>DTOs or VOs</strong>
<p>The traditional enterprise pattern that addresses this task of transferring objects full of data from one system to another is the Data Transfer Object (DTO; sometimes called the Value Object, or VO). Often, weightier code than we&#8217;ll need was used to get the data needed in an object out of the database and into a lightweight object, the DTO, and then that object was transferred across the wire and used as needed. In this case, EJB 3.0 does all the work of getting the data into and out of the database for us. The entities fulfill the role of defining the mapping to the database tables and holding the data for transfer and manipulation.</p> 

<p>Note that most of the Cairngorm projects you&#8217;ll see use VO instead of DTO, although most of the enterprise Java world has standardized on DTO. They mean the same thing.</p>

<div class="ap_r" style="width:180px;"><a href="http://www.oreilly.com/catalog/9780596514402/?CMP=ILC-dm_nav_related-books" target="_blank"><img border="0" src="http://www.oreilly.com/catalog/covers/9780596514402_cat.gif" width="180" height="233" /></a>
<div class="apcaption"><a href="http://www.oreilly.com/catalog/9780596514402/?CMP=ILC-dm_nav_related-books" target="_blank">Get your copy of Tony Hillerson's Enterprise Application Development with Flex.</a></div></div><strong>Session Beans</strong>
<p>Along with entity beans, session beans are a type of class that EJB 3.0 specifies for providing services and managing business processes. Of course, central to these processes are entities that are important to the business logic. Session beans come in two flavors: stateful and stateless. Stateful session beans have a concept of a session which spans multiple requests and keeps a &#8220;conversational state&#8221; from one request to another. A conversational state is simply all the important information about a client&#8217;s interactions with the bean over the lifespan of the bean. The EJB container, such as JBoss, keeps the bean ready for the next call from its previous client.</p>

<p>Our sample application, like most, if not all, RIAs, has no need for the beans to keep track of a user&#8217;s state. State is generally kept on the client with RIAs, because the client stays in memory and isn&#8217;t limited by the request-response cycle, as a simple web page is. Our sessions will be conducted one call at a time through the other type of session bean, the stateless bean, which is the same as a stateful bean but without keeping any state. The stateful beans will act as Data Access Objects (DAOs) for our entities. That just means they&#8217;ll get the objects into and out of the database, and they&#8217;ll be responsible for any business logic at those points.</p>

<p>Here&#8217;s the syntax for creating a stateless session bean:</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 30px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
@Stateless
@Local(value={BookDAO.<span class="category1">class</span>})
<span class="category1">public</span> <span class="category1">class</span> BookDAOBean <span class="category1">implements</span> BookDAO {
 &amp;#133;</pre>
</code>
 
</div></div>

<p>Just like @Entity does for an entity bean, @Stateless and its counterpart, @Stateful, mark a class as a session bean. One other requirement, though, is that the bean implements an interface that lets the container know which methods should be exposed to different requests. These requests could be local or remote, because beans can be distributed across different servers. The beans can have more than one interface to mark which methods are available to the different types of requests. We&#8217;ll only need to expose local access, so we&#8217;ll tell the container which class the local interface is with an @Local annotation. Here&#8217;s a look at that interface:</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 120px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
package lcds.examples.bookie.dao;
...
<span class="category1">public</span> <span class="category1">interface</span> BookDAO {
     <span class="category1">public</span> <span class="category1">void</span> persist(Book transientInstance);
     <span class="category1">public</span> <span class="category1">void</span> remove(Book persistentInstance);
     <span class="category1">public</span> Book merge(Book detachedInstance);
     <span class="category1">public</span> Book findById(<span class="category1">int</span> id);
     <span class="category1">public</span> List&lt;Book&gt; getAll();
     <span class="category1">public</span> List&lt;Book&gt; findByAuthor(Person author);
     <span class="category1">public</span> List&lt;Book&gt; findBySubject(Subject subject);
     <span class="category1">public</span> Collection&lt;Book&gt; findByName(<span class="category2">String</span> title);
     <span class="category1">public</span> <span class="category1">void</span> removeDetached(Book detachedInstance);
}</pre>
</code>
 
</div></div>


<p>These are all the things our code can do to a book or collection of books.</p>
<p>Here&#8217;s more of the code for the book session bean:</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 90px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
package lcds.examples.bookie.dao.beans;
&amp;#133;
@Stateless
@Local(value={BookDAO.<span class="category1">class</span>})
<span class="category1">public</span> <span class="category1">class</span> BookDAOBean <span class="category1">implements</span> BookDAO {
 
     @PersistenceContext
     <span class="category1">private</span> EntityManager entityManager;
 
     <span class="category1">public</span> <span class="category1">void</span> persist(Book transientInstance) {
           <span class="category1">try</span> {
                 entityManager.persist(transientInstance);
            } <span class="category1">catch</span> (RuntimeException re) {
                 <span class="category1">throw</span> re;
            }
      }
 
     <span class="category1">public</span> <span class="category1">void</span> remove(Book persistentInstance) {
           <span class="category1">try</span> {
                 entityManager.remove(persistentInstance);
            } <span class="category1">catch</span> (RuntimeException re) {
                 <span class="category1">throw</span> re;
            }
      }</pre>
</code>
 
</div></div>

<p>These two methods&#8212;persist and remove&#8212;take an instance of a book. persist should be called for entities that don&#8217;t yet exist in the database, and remove will end up removing an entity from the database. These methods call methods of the same name on an object of type EntityManager. Notice, though, that that object is never instantiated. It is, however, marked with an @PersistenceContext annotation. This is part of what being a session bean is about in EJB 3.0. The EntityManager is instantiated at runtime and the container gives the session bean the instance that matches the persistence context in which the bean is running. If there is more than one instance, the annotation can specify which one it wants, but in our example, the persistence context is just the one persistence unit, so all the beans in our persistence unit get the same entity manager. </p>

<p>This process&#8212;in which the container gives our object the right instance of an object it needs&#8212;is called dependency injection. The entity manager is injected into our session bean at runtime. The container instantiates the manager in the right way so that we don&#8217;t have to know how to do it in our code, because there may be many things we just won&#8217;t know while we&#8217;re writing the code. Let&#8217;s look at a few more methods to see the types of operations the rest of our beans will perform on their respective entities:</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 120px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
    <span class="category1">public</span> Book merge(Book detachedInstance) {
          <span class="category1">try</span> {
                Book result = 
                     entityManager.merge(detachedInstance);
                <span class="category1">return</span> result;
           } <span class="category1">catch</span> (RuntimeException re) {
                     <span class="category1">throw</span> re;
           }
     }

    <span class="category1">public</span> <span class="category1">void</span> removeDetached(Book detachedInstance) {
          remove(merge(detachedInstance));
     }</pre>
</code>
 
</div></div>

<p>persist and remove basically map to SQL&#8217;s insert and delete statements. merge fulfills two use cases. The first case maps directly onto the SQL update statement; merge will take the changes from an entity and queue them for update into the database. EJB has a concept of entities which are managed by an EntityManager, however. What really happens when the entity manager&#8217;s remove is called is that the entity is removed from being managed by the manager, which queues it for removal from the database. The object may still exist, though, because code may have a reference to it. It&#8217;s possible to put the object right back into the manager by saying merge.</p>

<p>This case illustrates the difference between a detached entity and a managed entity. So, what&#8217;s the difference between calling persist and merge with a detached entity? Nothing, really; either way, the object will be inserted if it doesn&#8217;t exist. persist will have a problem if the entity already existed in database form, though, whereas merge will not. </p>

<p>Because we&#8217;ll often be sending objects from the client side that may not have been pulled out of the database into the entity manager, we&#8217;ll pretty much always call merge for both new objects and updates to existing ones, just to be safe. This explains why I have the removeDetached method as well: sometimes we may want to delete an object that hasn&#8217;t been loaded into the entity manager yet, and we won&#8217;t know unless we make the process more complicated. If we try to remove a detached entity, the entity manager complains that it doesn&#8217;t know anything about this object. In this case, it&#8217;s easier to merge the object first to make sure it&#8217;s managed by the entity manager, and then to remove it.</p>

<div class="acode" style="overflow: auto; padding: 10px; height: 200px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
    <span class="category1">public</span> Book findById(<span class="category1">int</span> id) {
          <span class="category1">try</span> {
                Book instance = entityManager.find(Book.<span class="category1">class</span>, id);
                <span class="category1">return</span> instance;
           } <span class="category1">catch</span> (RuntimeException re) {
                <span class="category1">throw</span> re;
           }
     }
    
    <span class="category1">public</span> List&lt;Book&gt; getAll() {
          Query q = entityManager.createQuery(
                    "<span class="quote">from Book b</span>" +
                    "<span class="quote"> order by b.title</span>"
               );
               List&lt;Book&gt; results = q.getResultList();
                <span class="category1">return</span> results;
     }

    <span class="category1">public</span> List&lt;Book&gt; findByAuthor(Person author) {
          Query q = entityManager.createQuery(
               "<span class="quote">from Book b</span>" +
               "<span class="quote"> where b.author.id = :author_id</span>"
          );
          q.setParameter("<span class="quote">author_id</span>", author.getId());
          List&lt;Book&gt; results = q.getResultList();
          <span class="category1">return</span> results;
     }
    </pre>
</code>
 
</div></div>

<p>In the preceding code, I included a few more methods as examples of what we&#8217;ll do with session beans. findById calls the entity manager&#8217;s find(Class, int) method. It looks at the class to see where it&#8217;s mapped, and then it does a select to find the row that matches the ID. Simple.</p>

<p>getAll introduces us to a query. Queries are created from the entity manager. A standard query in EJB uses EJBQL, instead of SQL. EJBQL looks an awful lot like SQL, but it allows you to refer to classes instead of tables, and properties instead of columns. The results fit easily into a list.</p>

<p>findByAuthor shows another feature of a query in EJB 3.0. Just like SQL, EJBQL has a where clause. Notice that the syntax lets us specify a named parameter in the form : &lt;param name&gt;. On the line after we create the query, we call the setParameter method to get the author&#8217;s ID into that parameter, so the query will find all books that have a certain author ID.</p>

<p>Figure 13 shows the rest of the session beans in the data project.</p>

<div class="ap_c" style="margin: 16px;"><a href="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex/anatomy10_fig13.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex/anatomy10_fig13.jpg" alt="anatomy10_fig13.jpg" title="Click to enlarge" width="400"/></a><div class="acaption">Figure 13. The rest of the session beans in the data project</div></div>


<p>Next installment we're going to look at testing the Java part of our application using TestNG.  You can always find the entire series <a href="http://www.insideria.com/series-anatomy-flex.html">here</a>.</p>

]]>
      
    </content>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23198-comment:2016149</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23198" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-4.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-4.html#comment-2016149" />
    <title>Comment from Panna on 2008-03-26</title>
    <author>
        <name>Panna</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Hello Tony,<br />
I've purchased your book and I'm stumbling while running the <br />
 sample application.<br />
Maven can't build 4 artifacts.<br />
It's the same problem as Martin had.<br />
I've looked on the repo site manually but can't find them.<br />
It would be nice if you could help me out.</p>

<p>Kind regards.</p>]]>
    </content>
    <published>2008-03-26T16:07:41Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23198-comment:2016250</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23198" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-4.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-4.html#comment-2016250" />
    <title>Comment from Tony Hillerson on 2008-03-31</title>
    <author>
        <name>Tony Hillerson</name>
        <uri>http://thillerson.blogspot.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://thillerson.blogspot.com">
        <![CDATA[<p>@Panna - did you make sure to extract the maven repository file (http://examples.oreilly.com/9780596514402/m2_repository.zip) into the .m2 directory in your home directory?</p>]]>
    </content>
    <published>2008-04-01T04:00:21Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23198-comment:2066335</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23198" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-4.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-4.html#comment-2066335" />
    <title>Comment from Pravu Mishra on 2009-06-17</title>
    <author>
        <name>Pravu Mishra</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Hi,</p>

<p>The examples in this article contains code that uses  try-catch block for RuntimeException as mentioned below.</p>

<p> public Book merge(Book detachedInstance) {<br />
          try {<br />
                Book result = <br />
                     entityManager.merge(detachedInstance);<br />
                return result;<br />
           } catch (RuntimeException re) {<br />
                     throw re;<br />
           }</p>

<p>can we catch a RuntimeException and throw ir again ? Is there any chance the catch block would be executed?</p>

<p><br />
Thanks and Regards,<br />
Pravu Mishra.</p>]]>
    </content>
    <published>2009-06-17T08:34:36Z</published>
  </entry>

</feed
