<?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-3.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.23143-</id>
  <updated>2009-11-16T15:50:27Z</updated>
  <title>Comments for Anatomy of an Enterprise Flex RIA Part 9: Nouns and Entity Beans (http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-3.html)</title>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>
  <entry>
    <id>tag:www.insideria.com,2008://34.23143</id>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-3.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=23143" title="Anatomy of an Enterprise Flex RIA Part 9: Nouns and Entity Beans" />
    <published>2008-03-17T07:02:50Z</published>
    <updated>2009-06-08T15:57:17Z</updated>
    <title>Anatomy of an Enterprise Flex RIA Part 9: Nouns and Entity Beans</title>
    <summary>In the last installment we looked at our development lifecycle and the dependencies of our persistence layer. Now we&apos;re going to look at the actual code that makes up the persistence layer, Actionscript and Java.  Follow along at each stage of development, every Monday on InsideRIA.com.</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_part9.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex/riaseries_part9.jpg" alt="riaseries_part9.jpg" title="Click to enlarge" width="148"/></a></div>In the last installment we looked at our development lifecycle and the dependencies of our persistence layer. Now we're going to look at the actual code that makes up the persistence layer, Actionscript and Java.

<p>A very simple way to pick out the data we need to model and persist in the database is to look over our use cases and pick out the nouns. <span class="inlinecodeorange"><em>Nouns</em></span> are something we can say something about, such as &#8220;this book has a certain title.&#8221; <span class="inlinecodeorange"><em>Verbs</em></span> are actions that we need to allow our users to perform. Nouns become database tables and classes that map to those tables, and verbs become code that manipulates and acts on instances of the classes; simple, right? (Let&#8217;s not get into adjectives and adverbs just right now.)</p>

<p>A quick look at our use cases reveals five important nouns: </p>

<ul><li>Books</li><li>Subjects</li><li>Authors</li><li>Users</li><li>Reservations</li></ul>
For our purposes, let&#8217;s treat Authors and Users roughly the same, and call them People. That leaves us with the following:
<ul><li>Books</li><li>Subjects</li><li>People</li><li>Reservations</li></ul>

<p>So, Figure 10 shows our database schema based on those nouns.</p>

<div class="ap_c" style="margin: 16px;"><a href="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex_3/anatomy_fig10.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex_3/anatomy_fig10.jpg" alt="anatomy_fig10.jpg" title="Click to enlarge" width="400"/></a><div class="acaption">Figure 10. Database schema based on the nouns Books, Subjects, People, and Reservations</div></div>




<p>Now let&#8217;s create the Java classes which will be persisted into these tables. I like to follow the Ruby on Rails convention of naming the database tables as the plural of the noun and the object corresponding to the table in the singular. </p>

<p>Here&#8217;s the syntax for mapping a class to a table:</p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
@Entity
@Table(<span class="category2">name</span>="<span class="quote">books</span>")
<span class="category1">public</span> <span class="category1">class</span> Book {
 ...</pre>
</code>
 
</div></div>

<p><br />
<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><br />
<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>Inside <span class="yellowinlinecode"><em>src</em></span> is a directory for the main source of the project, called <span class="yellowinlinecode"><em>main</em></span>. At the same level is a folder for test code, called <span class="yellowinlinecode"><em>test</em></span>. The code goes in the <span class="yellowinlinecode"><em>main</em></span> and <span class="yellowinlinecode"><em>test</em></span> directories and is organized by the type of language&#8212;in this case, a <span class="yellowinlinecode"><em>java</em></span> directory holds the Java code in the data project directory, and a <span class="yellowinlinecode"><em>java</em></span> and <span class="yellowinlinecode"><em>flex</em></span> directory in the web project.  </p>


<p>This type of class is called an <span class="inlinecodeorange"><em>entity</em></span>, and it&#8217;s basically the same thing as a noun (something that has a name). This is one of the three bean types from EJB 3.0. We&#8217;ll run into the others, session beans and message-driven beans, soon. Notice that the class doesn&#8217;t have to extend anything, which is a change from previous versions of EJB. There are two annotations: one that deals with the at (<span class="inlinecodered">@</span>) signs next to them, and the <span class="inlinecodered">@Table</span> annotation which tells EJB to which table this class maps.</p>

<p>After mapping a class to a table, each column needs to be mapped to a set of &#8220;accessor methods.&#8221; Java convention has a name for a class with one or more of these sets of methods: a <span class="inlinecodeorange"><em>bean</em></span>. A class that follows a &#8220;bean pattern&#8221; has one or more &#8220;properties,&#8221; which are private variables, and a &#8220;getter&#8221; and &#8220;setter&#8221; method to allow the class to protect access to that property. For instance, here&#8217;s some more code from the <span class="inlinecodeered">Book</span> class:</p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
package lcds.examples.bookie.entity;
...
@Entity
@Table(<span class="category2">name</span>="<span class="quote">books</span>")
<span class="category1">public</span> <span class="category1">class</span> Book {
 
     <span class="category1">private</span> <span class="category2">String</span> title;
     
 ...
     @Column(<span class="category2">name</span>="<span class="quote">title</span>")
     <span class="category1">public</span> <span class="category2">String</span> <span class="category2">getTitle</span>() {
           <span class="category1">return</span> title;
      }
     
     <span class="category1">public</span> <span class="category1">void</span> <span class="category2">setTitle</span>(<span class="category2">String</span> title) {
           <span class="category1">this</span>.title = title;
      }
 ...</pre>
</code>
 
</div></div>

<p>The book has a private property, <span class="inlinecodered">title</span>, and two public methods, <span class="inlinecodered">getTitle</span> and <span class="inlinecodered">setTitle</span>. This is the idea of an object in object-oriented programming: data and methods to get at the data, which allow the object to protect the data from outside access. There&#8217;s one more <span class="inlinecodered">@</span> sign here: the <span class="inlinecodered">@Column</span> annotation tells EJB that the <span class="inlinecodered">getTitle</span> and <span class="inlinecodered">setTitle</span> methods are the accessor methods for a property that goes in a column called &#8220;Title&#8221;.</p>

<p>One more step I&#8217;m going to take is to generalize some of the common parts of the entities into a <span class="inlinecodered">BaseEntity</span> class. A nice bit of agility we can achieve here is to have an EJB listener put the created and updated timestamps on each record for us. We just have to make sure each table has a &#8220;created_on&#8221; and &#8220;updated_on&#8221; column. Now, by setting up <span class="inlinecodered">BaseEntity</span> with an <span class="inlinecodered">EntityListener</span> annotation, we&#8217;ll get an instance of that object called whenever an EJB life cycle event happens:</p>

 <div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
package lcds.examples.bookie.entity.listeners;
...
@MappedSuperclass
@EntityListeners({CreateUpdateTimestampEventListener.<span class="category1">class</span>})
<span class="category1">public</span> abstract <span class="category1">class</span> BaseEntity <span class="category1">implements</span> Serializable {
     
     <span class="category1">private</span> Integer id;
     <span class="category1">private</span> Calendar createdOn;
     <span class="category1">private</span> Calendar updatedOn;
 
     @Id
     @GeneratedValue(strategy=GenerationType.AUTO)
     @Column(<span class="category2">name</span>="<span class="quote">id</span>")
     <span class="category1">public</span> Integer getId() {
           <span class="category1">return</span> id;
      }
 
     <span class="category1">public</span> <span class="category1">void</span> setId(Integer id) {
           <span class="category1">this</span>.id = id;
      }
     
     @Temporal(TemporalType.TIMESTAMP)
     @Column(<span class="category2">name</span>="<span class="quote">created_on</span>")
     <span class="category1">public</span> Calendar getCreatedOn() {
           <span class="category1">return</span> createdOn;
      }
 
     <span class="category1">public</span> <span class="category1">void</span> setCreatedOn(Calendar createdOn) {
           <span class="category1">this</span>.createdOn = createdOn;
      }
 
     @Temporal(TemporalType.TIMESTAMP)
     @Column(<span class="category2">name</span>="<span class="quote">updated_on</span>")
     <span class="category1">public</span> Calendar getUpdatedOn() {
           <span class="category1">return</span> updatedOn;
      }
 
     <span class="category1">public</span> <span class="category1">void</span> setUpdatedOn(Calendar updatedOn) {
           <span class="category1">this</span>.updatedOn = updatedOn;
      }
 ...</pre>
</code>
 
</div></div>

<p>The benefit of creating this <span class="inlinecodered">BaseEntity</span> is that we can put common code such as the id property here. Every class that extends <span class="inlinecodered">BaseEntity</span> gets an <span class="inlinecodered">id for free. Just remember that it needs to be in the table for that class too.</p>

<p>Notice that instead of an <span class="inlinecodered">@Entity, BaseEntity</span> is annotated as an <span class="inlinecodered">@MappedSuperclass</span>, which means that it doesn&#8217;t go directly in the database, but the fields in it will when they become part of another object, most likely when that object extends the mapped superclass.</p>

<p>As I mentioned, we can put the timestamp code here too. Each table we map to an entity should have a &#8220;created_on&#8221; and &#8220;updated_on&#8221; column. If the entity extends <span class="inlinecodered">BaseEntity</span>, those columns will be populated automatically, which is pretty useful. Notice the new annotation, <span class="inlinecodered">@Temporal</span>, which tells EJB to map the data in a certain date-type property to a date-type column in the database. </p>

<p>How does the automatic part happen? By using an entity listener. Notice the <span class="inlinecodered">@EntityListeners</span> annotation, which contains an array of listeners. Entity listeners have methods that EJB calls automatically at different points in the entity&#8217;s life cycle&#8212;for instance, when the object is created, when it&#8217;s updated, or when it&#8217;s removed. Table 6 lists and describes the possible life cycle event annotations.</p>

<table width="430"><tr><th scope="col" colspan="2" style="font-size: 11px; font-weight: bold; color: #525252; border: 1px solid #d7d7d7; letter-spacing: 2px;text-transform: uppercase; text-align: left; padding: 6px 6px 6px 12px; background-color: #f2f2f2;">Table 6:  life cycle event annotations</th></tr><tr><th scope="col" style="font-size: 11px; font-weight: bold; color: #525252; border: 1px solid #d7d7d7; letter-spacing: 2px;text-transform: uppercase; text-align: left; padding: 6px 6px 6px 12px; background-color: #f2f2f2;">life cycle event annotation</th><th valign="top" scope="col" style="font-size: 11px; font-weight: bold; color: #525252; border: 1px solid #d7d7d7; letter-spacing: 2px;text-transform: uppercase; text-align: left; padding: 6px 6px 6px 12px; background-color: #f2f2f2;">DESCRIPTION</th></tr><tr><td valign="top" style="width: 40%; border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">@PrePersist</td><td valign="top" style="width: 60%; border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">Method called before the entity is written to the database</td></tr><tr><td valign="top" style="border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">@PostPersist</td><td valign="top" style="border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">Method called directly after the entity is written to the database</td></tr><tr><td valign="top" style="border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">@PreUpdate</td><td valign="top" style="border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">Method called before the entity is updated in the database</td></tr><tr><td valign="top" style="border-left: 1px solid #d7d7d7;border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">@PostUpdate</td><td valign="top" style="border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">Method called after the entity is updated in the database</td></tr><tr><td valign="top" style="border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">@PreRemove </td><td valign="top" style="border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">Method called before the entity is removed</td></tr><tr><td valign="top" style="border-left: 1px solid #d7d7d7;border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;"> @PostRemove</td><td valign="top" style="border: 1px solid #d7d7d7; background: #fff; padding: 6px 6px 6px 12px; color: #525252;">Method called after the entity is removed</td></tr></table>

<p>And here&#8217;s a look at our entity listener:</p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
<span class="category1">public</span> <span class="category1">class</span> CreateUpdateTimestampEventListener {
     
     @PrePersist
     <span class="category1">public</span> <span class="category1">void</span> setCreateDateTime(<span class="category2">Object</span> entity) 
               throws IllegalArgumentException {
           <span class="category1">try</span> {
                 BaseEntity stampable = (BaseEntity)entity;
                 stampable.setCreatedOn(<span class="category1">new</span> GregorianCalendar());
            } <span class="category1">catch</span> (Exception e) {
                 ...
            }
      }
     
     @PreUpdate
     <span class="category1">public</span> <span class="category1">void</span> setUpdateDateTime(<span class="category2">Object</span> entity)
               throws IllegalArgumentException {
           <span class="category1">try</span> {
                 BaseEntity stampable = (BaseEntity)entity;
                 stampable.setUpdatedOn(<span class="category1">new</span> GregorianCalendar());
            } <span class="category1">catch</span> (Exception e) {
                 ...
            }
      }
     
}</pre>
</code>
 
</div></div>


<p>Figure 11 shows all the mapped entities in the data project in the <span class="inlinecodered">lcds.examples.bookie.entity</span> package.</p>

<div class="ap_c" style="margin: 16px;"><a href="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex_3/anatomy_fig11.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex_3/anatomy_fig11.jpg" alt="anatomy_fig11.jpg" title="Click to enlarge" width="400"/></a><div class="acaption">Figure 11. Mapped entities in the data project</div></div>




<p>Now let&#8217;s look at modeling the entities in ActionScript. Here&#8217;s the ActionScript class corresponding to the <span class="inlinecodered">Book</span> entity:</p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
package lcds.examples.bookie.entity {
     
     <span class="category1">import</span> lcds.examples.bookie.entity.BaseEntity;
     <span class="category1">import</span> lcds.examples.bookie.entity.Subject;
 
     [Managed]
     [RemoteClass(alias="<span class="quote">lcds.examples.bookie.entity.Book</span>")]
     <span class="category1">public</span> <span class="category1">class</span> Book <span class="category1">extends</span> BaseEntity {
  
           <span class="category1">public</span> <span class="category1">var</span> subject:Subject;
           <span class="category1">public</span> <span class="category1">var</span> title:<span class="category2">String</span>;
           <span class="category1">public</span> <span class="category1">var</span> isbn:<span class="category2">String</span>;
           <span class="category1">public</span> <span class="category1">var</span> author:Person;
  
      }
}</pre>
</code>
 
</div></div>


<p>Notice how the package is the same as the Java package, to minimize confusion. The ActionScript <span class="inlinecodered">Book</span> also extends a <span class="inlinecodered">BaseEntity</span>, which we&#8217;ll see in a second. Notice the <span class="inlinecodered">[RemoteClass] metadata. Its <span class="inlinecodered">alias</span> property tells LCDS which Java class it maps to. This is a compiler directive to map that string to this class. Then, whenever the LCDS code in the Flash Player gets an instance of a <span class="inlinecodered">java</span> class with that qualified name, it knows to look up this class and create an instance of it. No messy or fragile XML encoding and decoding!</p>
<p>The <span class="inlinecodered">[Managed]</span> metadata tag tells Flex to watch objects of this type for changes which, depending on settings, may automatically make their way back to LCDS.</p>

<p>One last thing: Flex doesn&#8217;t have the same concept of a &#8220;bean pattern&#8221; that Java does (it does have a nicer getter/setter pattern, though), so any properties in ActionScript beans that map to JavaBeans should be public properties. No biggie; just treat the data in these objects nicely and everything will be fine.</p>

<p>The ActionScript entities are in the <span class="inlinecodered">lcds.examples.bookie.entity</span> package in the <span class="inlinecodered">bookie-ui</span> project (see Figure 12).</p>

<div class="ap_c" style="margin: 16px;"><a href="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex_3/anatomy_fig12.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/upload/2008/03/anatomy_of_an_enterprise_flex_3/anatomy_fig12.jpg" alt="anatomy_fig12.jpg" title="Click to enlarge" width="400"/></a><div class="acaption">Figure 12. ActionScript entities</div></div>



<p>Now that the entities are modeled on both the Flex and the Java side, we&#8217;ll be able to call services on the Java side and LCDS will be able to translate ActionScript objects in the call to Java objects. Java will do what it needs to do, and if necessary, Java will translate those objects from Java back to ActionScript. This is only a basic example of what LCDS provides us. We&#8217;ll see more of LCDS in action in the coming sections of this shortcut.</p>

<p>Next time we'll look at the service layer from the Java point of view. 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.23143-comment:2015936</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23143" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-3.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/03/anatomy-of-an-enterprise-flex-3.html#comment-2015936" />
    <title>Comment from Jennifer Lech on 2008-03-17</title>
    <author>
        <name>Jennifer Lech</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>none</p>]]>
    </content>
    <published>2008-03-17T14:55:33Z</published>
  </entry>

</feed
