<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.feedsky.com/styles/feedsky2.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link href="http://feed.feedsky.com/xiong2009" type="application/rss+xml" rel="self"></atom:link><fs:self_link href="http://feed.feedsky.com/xiong2009" type="application/rss+xml"></fs:self_link><lastBuildDate>Mon, 17 Aug 2009 02:52:00 GMT</lastBuildDate><title>良子</title><description>做最好的自己</description><link>http://blog.csdn.net/xiong2009</link><language>zh-cn</language><copyright>Copyright &amp;copy; xiong2009</copyright><pubDate>Tue, 14 Feb 2012 16:45:09 GMT</pubDate><image><url>http://static.blog.csdn.net/images/logo.gif</url><link>http://blog.csdn.net</link></image><item><title>[转]主数据管理(MDM)的成熟度</title><link>http://blog.csdn.net/xiong2009/article/details/4454597</link><description>&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;strong style=&quot;mso-bidi-font-weight: normal;&quot;&gt;&lt;span style=&quot;font-size: 14pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt;&quot;&gt;主数据管理&lt;span lang=&quot;EN-US&quot;&gt;(MDM)&lt;/span&gt;的成熟度&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot; lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;全写&lt;span lang=&quot;EN-US&quot;&gt;Master Data Management&lt;/span&gt;，翻译为主数据管理或元数据管理。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;strong style=&quot;mso-bidi-font-weight: normal;&quot;&gt;什么是&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;企业主数据是用来描述企业核心业务实体的数据，比如客户、合作伙伴、员工、产品、物料单、账户等；它是具有高业务价值的、可以在企业内跨越各个业务部门被重复使用的数据，并且存在于多个异构的应用系统中。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;strong style=&quot;mso-bidi-font-weight: normal;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;主数据和主数据管理的概念&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;企业主数据可以包括很多方面，除了常见的客户主数据之外，不同行业的客户还可能拥有其他各种类型的主数据，例如：对于电信行业客户而言，电信运营商提供的各种服务可以形成其产品主数据；对于航空业客户而言，航线、航班是其企业主数据的一种。对于某一个企业的不同业务部门，其主数据也不同，例如市场销售部门关心客户信息，产品研发部门关心产品编号、产品分类等产品信息，人事部门关心员工机构，部门层次关系等信息。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;数据管理的范畴和主数据管理的概念&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot; lang=&quot;EN-US&quot;&gt;&lt;img src=&quot;http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0904loulj/image002.gif&quot; alt=&quot;数据管理的范畴&quot; width=&quot;312&quot; height=&quot;177&quot; /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　如图所示，企业数据管理的内容及范畴通常包括交易数据、主数据以及元数据。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; line-height: 150%; mso-pagination: widow-orphan; mso-list: l2 level1 lfo2; tab-stops: list 21.0pt;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt; mso-fareast-font-family: Wingdings;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;mso-list: Ignore;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;交易数据：用于纪录业务事件，如客户的订单，投诉记录，客服申请等，它往往用于描述在某一个时间点上业务系统发生的行为。&lt;span lang=&quot;EN-US&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; line-height: 150%; mso-pagination: widow-orphan; mso-list: l2 level1 lfo2; tab-stops: list 21.0pt;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt; mso-fareast-font-family: Wingdings;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;mso-list: Ignore;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;主数据：主数据则定义企业核心业务对象，如客户、产品、地址等，与交易流水信息不同，主数据一旦被记录到数据库中，需要经常对其进行维护，从而确保其时效性和准确性；主数据还包括关系数据，用以描述主数据之间的关系，如客户与产品的关系、产品与地域的关系、客户与客户的关系、产品与产品的关系等。 &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; line-height: 150%; mso-pagination: widow-orphan; mso-list: l2 level1 lfo2; tab-stops: list 21.0pt;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt; mso-fareast-font-family: Wingdings;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;mso-list: Ignore;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;元数据：即关于数据的数据，用以描述数据类型、数据定义、约束、数据关系、数据所处的系统等信息。&lt;span lang=&quot;EN-US&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;主数据管理是指一整套的用于生成和维护企业主数据的规范、技术和方案，以保证主数据的完整性、一致性和准确性&lt;span lang=&quot;EN-US&quot;&gt; ( &amp;ldquo; The set of disciplines, technologies, and solutions used to create and maintain consistent, complete, contextual and accurate business data for all stakeholders (users, applications, data warehouses, processes, companies, trading partners, customers, etc.) across and beyond the enterprise &amp;rdquo; ) &lt;/span&gt;。主数据管理的典型应用有&lt;span lang=&quot;EN-US&quot;&gt; Customer Data Integration &amp;mdash;&lt;/span&gt;客户数据管理和&lt;span lang=&quot;EN-US&quot;&gt; Product Information Integraiton &amp;mdash;&lt;/span&gt;产品数据管理。&lt;/span&gt;&lt;a name=&quot;2.1.2.图2._主数据管理的信息流|outline&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 14.25pt; text-align: left; mso-pagination: widow-orphan;&quot; align=&quot;left&quot;&gt;&lt;span style=&quot;mso-bookmark: '2.1.2.图2._主数据管理的信息流|outline';&quot;&gt;&lt;span style=&quot;font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;图&lt;span lang=&quot;EN-US&quot;&gt; 2. &lt;/span&gt;主数据管理的信息流&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 14.25pt; text-align: left; mso-pagination: widow-orphan;&quot; align=&quot;left&quot;&gt;&lt;span style=&quot;mso-bookmark: '2.1.2.图2._主数据管理的信息流|outline';&quot;&gt;&lt;span style=&quot;font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot; lang=&quot;EN-US&quot;&gt;&lt;img src=&quot;http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0904loulj/image004.gif&quot; alt=&quot;主数据管理的信息流&quot; width=&quot;468&quot; height=&quot;257&quot; /&gt;&lt;br /&gt;&lt;/span&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;一般来说，主数据管理系统从&lt;span lang=&quot;EN-US&quot;&gt; IT &lt;/span&gt;建设的角度而言都会是一个相对复杂的系统，它往往会和企业数据仓库&lt;span lang=&quot;EN-US&quot;&gt; / &lt;/span&gt;决策支持系统以及企业内的各个业务系统发生关系，技术实现上也会涉及到&lt;span lang=&quot;EN-US&quot;&gt; ETL&lt;/span&gt;、&lt;span lang=&quot;EN-US&quot;&gt;EAI&lt;/span&gt;、&lt;span lang=&quot;EN-US&quot;&gt;EII &lt;/span&gt;等多个方面，如图&lt;span lang=&quot;EN-US&quot;&gt; 2 &lt;/span&gt;所示，一个典型的主数据管理的信息流为：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; line-height: 150%; mso-pagination: widow-orphan; mso-list: l1 level1 lfo3; tab-stops: list 21.0pt;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;mso-list: Ignore;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.&lt;/span&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;某个业务系统触发对企业主数据的改动；&lt;span lang=&quot;EN-US&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; line-height: 150%; mso-pagination: widow-orphan; mso-list: l1 level1 lfo3; tab-stops: list 21.0pt;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;mso-list: Ignore;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;2.&lt;/span&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;主数据管理系统将整合之后完整、准确的主数据分发给所有有关的应用系统；&lt;span lang=&quot;EN-US&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; line-height: 150%; mso-pagination: widow-orphan; mso-list: l1 level1 lfo3; tab-stops: list 21.0pt;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;mso-list: Ignore;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.&lt;/span&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;主数据管理系统为决策支持和数据仓库系统提供准确的数据源。&lt;span lang=&quot;EN-US&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;因此对于主数据管理系统的建设，要从建设初期就考虑整体的平台框架和技术实现。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;strong style=&quot;mso-bidi-font-weight: normal;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;的意义&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;如图&lt;span lang=&quot;EN-US&quot;&gt; 3 &lt;/span&gt;所示：集成、共享、数据质量、数据治理是主数据管理的四大要素，主数据管理要做的就是从企业的多个业务系统中整合最核心的、最需要共享的数据（主数据），集中进行数据的清洗和丰富，并且以服务的方式把统一的、完整的、准确的、具有权威性的主数据分发给全企业范围内需要使用这些数据的操作型应用和分析型应用，包括各个业务系统、业务流程和决策支持系统等。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;主数据管理使得企业能够集中化管理数据，在分散的系统间保证主数据的一致性，改进数据合规性、快速部署新应用、充分了解客户、加速推出新产品的速度。从&lt;span lang=&quot;EN-US&quot;&gt; IT &lt;/span&gt;建设的角度，主数据管理可以增强&lt;span lang=&quot;EN-US&quot;&gt; IT &lt;/span&gt;结构的灵活性，构建覆盖整个企业范围内的数据管理基础和相应规范，并且更灵活地适应企业业务需求的变化。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;以客户主数据为例，客户主数据是目前企业级客户普遍面临的一个问题，在大多数企业中，客户信息通常分散于&lt;span lang=&quot;EN-US&quot;&gt; CRM &lt;/span&gt;等各个业务系统中，而每个业务系统中都只有客户信息的片断，即不完整的客户信息，但却缺乏企业级的完整、统一的单一客户视图，结果导致企业不能完全了解客户，无法协调统一的市场行为，导致客户满意度下降，市场份额减少。因此，建立客户主数据系统的目的在于：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; line-height: 150%; mso-pagination: widow-orphan; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt; mso-fareast-font-family: Wingdings;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;mso-list: Ignore;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;整合并存储所有业务系统和渠道的客户及潜在客户的信息：一方面从相关系统中抽取客户信息，并完成客户信息的清洗和整合工作，建立企业级的客户统一视图；另一方面，客户主数据管理系统将形成的统一客户信息以广播的形式同步到其他各个系统，从而确保客户信息的一致；&lt;span lang=&quot;EN-US&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; line-height: 150%; mso-pagination: widow-orphan; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt; mso-fareast-font-family: Wingdings;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;mso-list: Ignore;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;为相关的应用系统提供联机交易支持，提供客户信息的唯一访问入口点，为所有应用系统提供及时和全面的客户信息；服务于&lt;span lang=&quot;EN-US&quot;&gt; OCRM &lt;/span&gt;系统，充分利用数据的价值，在所有客户接触点上提供更多具有附加价值的服务；&lt;span lang=&quot;EN-US&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; line-height: 150%; mso-pagination: widow-orphan; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt; mso-fareast-font-family: Wingdings;&quot; lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;mso-list: Ignore;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;实现&lt;span lang=&quot;EN-US&quot;&gt; SOA &lt;/span&gt;的体系结构：建立客户主数据系统之前，数据被锁定在每一个应用系统和流程中，建立主数据管理系统之后，数据从应用系统中被释放出来，并且被处理成为一组可重用的服务，被各个应用系统调用。 &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;strong style=&quot;mso-bidi-font-weight: normal;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;的模式&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　元数据管理涉及到各个层次的元数据，管理的内容包括元数据的获取、元数据的更新、使用和面向应用项目的元数据使用处理等多个方面。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　元数据的管理涉及数据库、数据处理软件、数据使用系统、面向应用的数据分析等各个环节。下面给出了一种普通意义的以元数据信息系统为基础的元数据管理模式：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　通常意义上的元数据管理是指元数据通过各种途径形成后，对其内容的添加、删除、更新等涉及内容改变的操作和元数据内容检索、查询、放置、组织等常规性元数据操作，从这种意义上元数据的管理可以通过两种方式实现，即系统管理模式和用户管理模式。系统管理模式是面向数据库的，由数据库管理系统专业人员完成，数据用户只有使用权，没有元数据的操作权，数据应用项目中新生成的数据集的元数据也有应用系统传递给数据库管理员，然后由数据库管理员统一管理。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　这种方式中，数据在处理过程中形成的动态元数据很难及时记录下来。另一种管理方式是用户管理模式，它是面向应用项目的，即允许某些数据用户在数据应用元数据的变动信息直接反馈给元数据库，这样则能保证元数据的动态更新和新生成数据集元数据的及时捕获及写入元数据文件。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　但这种模式中数据用户的权限要适当的控制，以避免数据库的破坏。通常对元数据的管理是采用两者结合的模式。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;主数据（&lt;span lang=&quot;EN-US&quot;&gt;MD Master Data&lt;/span&gt;）指系统间共享数据（例如，客户、供应商、账户和组织部门相关数据）。与记录业务活动，波动较大的交易数据相比，主数据（也称基准数据）变化缓慢。在正规的关系数据模型中，交易记录（例如，订单行项）可通过关键字（例如，订单头或发票编号和产品代码）调出主数据。主数据必须存在并加以正确维护，才能保证交易系统的参照完整性。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;从报告或维度建模角度看，主数据指基于其组织或配置指标的维度或层次，而不是实际情况或其自身测量结果。例如，收入、成本和利润是实际情况，而时间、地点、客户和供应商是维度。应根据以下因素或更多因素综合考虑主数据：企业绩效管理报告（如利润或收入计划随产品、客户、账户等产生的变化）要求综合多个系统的主数据。遵从报告要求一致性主数据。同步交易系统处理特定客户（如提供具体报价）或供应商（如指定采购的首选供应商）。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;主数据管理&lt;span lang=&quot;EN-US&quot;&gt;(MDM)&lt;/span&gt;的成熟度&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot; lang=&quot;EN-US&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　根据主数据管理实施的复杂程度，参照&lt;span lang=&quot;EN-US&quot;&gt;Jill Dyche, Evan Levy&lt;/span&gt;的观点大体可以把主数据管理可以分为五个层次，从低到高反映了主数据管理&lt;span lang=&quot;EN-US&quot;&gt;(MDM)&lt;/span&gt;的不同成熟度。下面我们简单介绍一下这五个层次：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan; mso-outline-level: 1;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;strong&gt;&lt;span lang=&quot;EN-US&quot;&gt;Level 0 &lt;/span&gt;：没有实施任何主数据管理&lt;span lang=&quot;EN-US&quot;&gt;(MDM)&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　在&lt;span lang=&quot;EN-US&quot;&gt;Level 0&lt;/span&gt;的情况下，意味着企业的各个应用之间没有任何的数据共享，整个企业没有数据定义元素存在。比如，一个公司销售很多产品，对这些产品的生产和销售由多个独立的系统来处理，各个系统独立处理产品数据并拥有自己独立的产品列表，各个系统之间不共享产品数据。在&lt;span lang=&quot;EN-US&quot;&gt;Level 0, &lt;/span&gt;每个独立的应用负责管理和维护自己的关键数据&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;比如产品列表、客户信息等&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;，各个系统间不共享这些信息，这些数据是不连通的。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan; mso-outline-level: 1;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;strong&gt;&lt;span lang=&quot;EN-US&quot;&gt;Level 1 &lt;/span&gt;：提供列表&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　不管公司大还是小，列表管理是我们常用的一种方式。在公司内部，会通过手工的方式维护一个逻辑或物理的列表。当各个异构的系统和用户需要某些数据的时候，就可以索取该列表了。对于这个列表的维护，包括数据添加、删除、更新以及冲突处理，都是由各个部门的工作人员通过一系列的讨论和会议进行处理的。业务规则&lt;span lang=&quot;EN-US&quot;&gt;(Business Rules)&lt;/span&gt;是用来反映价值的一致性，当业务规则发生改变或者出现类似的情况时，这样高度手工管理的流程容易发生错误。由于列表管理是通过手工管理的，其列表维护的质量取决于谁参加了变更管理流程，一旦某人缺席，将会影响列表的维护。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 1&lt;/span&gt;比&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 0&lt;/span&gt;的不同就是，各个部门虽然还是独立维护各自的关键数据，但会通过列表管理维护一个松散的主数据列表，能够向其他各个部门提供其需要的数据。在&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 1&lt;/span&gt;中，数据变更决定以及数据变更操作都是由人来决定的，因此，只有人完成数据变更决定后才会变更数据。在实际情况中，虽然数据变更流程有严格的规定，但是由于缺乏集中的、基于规则的数据管理，当数据量比较大时，数据维护的成本会变的很高，效率也会很低。当主数据，比如客户信息、产品目录信息等数量比较少时，列表管理的方式是可行的，但是当产品目录或客户列表出现爆炸式增长以后，列表管理的变更流程将变得困难起来。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 1 &lt;/span&gt;依赖于人的协作。如果产品经理需要更新过后的产品价格列表，那需要联系&lt;span lang=&quot;EN-US&quot;&gt;ERP&lt;/span&gt;系统所有者，让其发送邮件给她。在企业范围内实现客户或产品列表就如同维护不同部门之间人们的关系一样。如果客户或产品存在层次或分组，列表将很难提供，并且通常在&lt;span lang=&quot;EN-US&quot;&gt;Level 1&lt;/span&gt;因为过于复杂难以被管理。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan; mso-outline-level: 1;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;strong&gt;&lt;span lang=&quot;EN-US&quot;&gt;Level 2 &lt;/span&gt;：同等访问&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;通过接口的方式，各个系统与主数据主机之间直接互联&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 2&lt;/span&gt;与&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 1&lt;/span&gt;相比，引入了对主数据的&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;自动&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;管理。通过建立数据标准，定义对存储在中央知识库&lt;span lang=&quot;EN-US&quot;&gt;(Central Repository)&lt;/span&gt;中详细数据的访问和共享，为各个系统间共享使用数据提供了严密的支持。中央知识库&lt;span lang=&quot;EN-US&quot;&gt;(Central Repository)&lt;/span&gt;通常会被称为&lt;span lang=&quot;EN-US&quot;&gt;&amp;ldquo;&lt;/span&gt;主数据主机&lt;span lang=&quot;EN-US&quot;&gt;(Master Data Host)&amp;rdquo;&lt;/span&gt;。这个知识库可以是一个数据库或者一个应用系统，通过在线的方式支持数据的访问和共享。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　创建、读取、更新和删除&lt;span lang=&quot;EN-US&quot;&gt; (CRUD)&lt;/span&gt;是处理基本功能的典型编程术语。即便在&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;中，&lt;span lang=&quot;EN-US&quot;&gt;CRUD&lt;/span&gt;处理也是基本功能。你的数据库如果仅仅支持&lt;span lang=&quot;EN-US&quot;&gt;CRUD&lt;/span&gt;处理并不意味着你实现了&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;。&lt;span lang=&quot;EN-US&quot;&gt; MDM Level 2&lt;/span&gt;引入了&lt;span lang=&quot;EN-US&quot;&gt;&amp;ldquo;&lt;/span&gt;同等访问&lt;span lang=&quot;EN-US&quot;&gt;&amp;rdquo;(peer-based access)&lt;/span&gt;，也就是说一个应用可以调用另一个应用来更新或刷新需要的数据。当&lt;span lang=&quot;EN-US&quot;&gt;CRUD&lt;/span&gt;处理规则定义完成后，&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 2 &lt;/span&gt;需要客户或&lt;span lang=&quot;EN-US&quot;&gt;&amp;ldquo;&lt;/span&gt;同等&lt;span lang=&quot;EN-US&quot;&gt;&amp;rdquo;&lt;/span&gt;应用格式化请求&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;和数据&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;，以便和&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;知识库保持一致。&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;知识库提供集中的数据存储和供应&lt;span lang=&quot;EN-US&quot;&gt;(provisioning)&lt;/span&gt;。在这个阶段，&lt;span style=&quot;color: red;&quot;&gt;规则管理&lt;/span&gt;、&lt;span style=&quot;color: red;&quot;&gt;数据质量&lt;/span&gt;和&lt;span style=&quot;color: red;&quot;&gt;变更管理&lt;/span&gt;必须在企业范围内作为附加功能定制构建。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　比如，一个数据库或一个打包应用&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;比如一个销售自动化系统&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;对外部应用提供数据访问功能。当一个外部应用&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;比如呼叫中心应用&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;需要增加一个客户，这个外部应用将提交一个事务，请求数据所有者增加一个客户条目。主数据主机&lt;span lang=&quot;EN-US&quot;&gt;(Master Data Host)&lt;/span&gt;将增加数据并告知外部应用。&lt;span lang=&quot;EN-US&quot;&gt;CRUD&lt;/span&gt;处理方式比纸上办公有了很大提高，其是基于会话的数据管理。在&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 1&lt;/span&gt;，数据变更是基于手工的方式。在&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 2&lt;/span&gt;，数据变更是自动完成的&lt;span lang=&quot;EN-US&quot;&gt;&amp;mdash;&lt;/span&gt;通过由具体技术实现的标准流程，允许多应用系统修改数据。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 2&lt;/span&gt;可以支持不同的应用使用和变更单一、共享的数据知识库。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 2 &lt;/span&gt;需要每个同等应用理解基本的业务规则以便访问主列表、与主列表进行交互。因此，每个同等应用必须正确恰当地创建、增加、更新和删除数据。授权应用有责任坚持数据管理原则和约束。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan; mso-outline-level: 1;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;strong&gt;&lt;span lang=&quot;EN-US&quot;&gt;Level 3 &lt;/span&gt;：集中总线处理&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　与&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 2&lt;/span&gt;相比，&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 3&lt;/span&gt;打破了各个独立应用的组织边界，使用各个系统都能接受的数据标准统一建立和维护主数据&lt;span lang=&quot;EN-US&quot;&gt;(MDM Level 2&lt;/span&gt;的主数据主机上存储的数据还是按照各个系统分开存储的，没有真正的整合在一起&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　集中处理意味着为&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;构建了一个通用的、基于目标构建的平台。大多数公司发现&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;正在挑战他们现有的&lt;span lang=&quot;EN-US&quot;&gt;IT&lt;/span&gt;架构：他们拥有太多的独立平台处理主数据。&lt;span lang=&quot;EN-US&quot;&gt; MDM Level 3 &lt;/span&gt;集中数据访问、控制跨不同应用和系统使用数据。这极大的降低了应用数据访问的复杂性，大大简化了面向数据规则的管理，使&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;比一个分散环境具有更多的功能和特点。企业主数据面临一致性的挑战。数据在不同的地方存在，数据所代表的含义也是不同的，数据的规则各个系统之间也是不一样的。集中&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;处理&lt;span lang=&quot;EN-US&quot;&gt;-&lt;/span&gt;通过一个公共的平台作为一个总线&lt;span lang=&quot;EN-US&quot;&gt;(HUB)-&lt;/span&gt;说明一个共识，从多个系统整合主题域数据，意味着使用集中、标准化的方法转换异构操作数据，不管其在源系统中是什么样子，都会被整合起来。在&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 3&lt;/span&gt;，公司对主题域内容采用集中管理方式。这意味着应用系统，作为消费者或使用主数据，拥有一个共识就是数据是主题数据内容的映像，打破了各个独立应用的组织边界。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 3&lt;/span&gt;支持分布主参考数据的存在。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;的核心之一就是保证所有系统都能接受数据表示的唯一公认方法。这有点类似于语言翻译，通过其他语言的翻译，英语已经称为一个全球性的语言。在&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 3&lt;/span&gt;，一个公司可以让任意两个系统共享数据和说对方的语言。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 3&lt;/span&gt;还降低了等同访问的复杂性。&lt;span lang=&quot;EN-US&quot;&gt;&quot;&lt;/span&gt;消费&lt;span lang=&quot;EN-US&quot;&gt;&quot;&lt;/span&gt;应用不再需要支持系统定位和操作逻辑。任何与源系统数据相关的分布式细节都会被&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;总线集中处理。在&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 3&lt;/span&gt;自动数据标准意味着：建立目标数据值表示和通过必要的步骤提供精确的主数据值捕获。在所有的分类中从&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 3&lt;/span&gt;开始第一次支持一致性的企业数据视图。数据质量规则在这里进行数据清洗和错误纠正。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan; mso-outline-level: 1;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　 &lt;strong&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;mso-spacerun: yes;&quot;&gt;&amp;nbsp;&lt;/span&gt;Level 4 &lt;/span&gt;：业务规则和政策支持&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　一旦数据从多个数据源整合在一起，主题域视图超越单独的应用并表现为一个企业视图，你将获得事实的单一版本。当事实的单一版本已经能够提供出来时，来自业务主管和执行人员的必然反应经常是：&lt;span lang=&quot;EN-US&quot;&gt;&amp;ldquo;&lt;/span&gt;证明它&lt;span lang=&quot;EN-US&quot;&gt;&amp;rdquo;&lt;/span&gt;。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 4&lt;/span&gt;可以保证主数据反映一个公司业务规则和流程，并证实其正确性。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 4&lt;/span&gt;通过引入主数据来支持规则，并对&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;总线以及其它外部系统进行完整性检查。由于多数公司相对比较复杂，影响业务数据访问和操作的规则以及策略&lt;span lang=&quot;EN-US&quot;&gt; (rules and policies)&lt;/span&gt;相对也比较复杂。假定任何一个单一系统可以包含并管理与主参考数据相关的各种类型的规则是不切实际的。因此，如果一个&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;总线真正打算提供企业范围内数据的精确性，&lt;span style=&quot;color: red;&quot;&gt;工作流和流程整合&lt;/span&gt;的支持是必不可少的。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　举例来说，在一个&lt;span lang=&quot;EN-US&quot;&gt;HMO&lt;/span&gt;内，需要多个应用来支持一个病人的护理。一个单一的访问&lt;span lang=&quot;EN-US&quot;&gt;(visit)&lt;/span&gt;可能包括入院、房间和床位分配、监控设备、化验、身体检查以及其他程序等。一旦一个病人准备离开医院，出院流程需要确保和这个病人相关的所有活动、资源都被结清。&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;技术在召集多个应用系统一起保证病人辨识方面是十分有效的，处理是正确的。虽然病人辨识很重要，业务规则整合同样重要。临床系统依靠一系列的业务流程和数据规则来辨别所有显著的病人详细资料。这包括返回所有基于房间的资源&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;监护设备、床位等&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;以得到有用的详细目录，当病人要出院时分解其所有的费用。&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;保证当&lt;span lang=&quot;EN-US&quot;&gt;John Smith&lt;/span&gt;出院时，正确的房间和设备放入到该&lt;span lang=&quot;EN-US&quot;&gt;John Smith&lt;/span&gt;的详细目录中，而不是其他的&lt;span lang=&quot;EN-US&quot;&gt;John Smith(&lt;/span&gt;正在另一个楼层做身体治疗&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;系统必须不仅支持基于规则的整合，还要能够整合外部的工作流。这些规则可能包括通过总线与临床系统交互或等待另一个系统或者人&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;有权限做出改变的人&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;审批。通过一个&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;总线，规则定义可以不仅局限在逻辑上，还可以依赖于其他系统的输入。当然，协调和审计数据意味着可以回退其他系统&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;或业务流程&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;来保证数据变化经过严格的审批，这样错误可以被发现并且事务在需要的时候可以被回滚。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 4&lt;/span&gt;提出对规则和策略扩展性的支持。 通过总线以一个灵活可持续的方式支持任何面向业务的规则集合这很重要。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　比如，如果一个商店经理更新一个产品的价格，总线系统需要能够和一个可信系统&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;比如，商品管理系统&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;进行协商以便使规则生效。详细规则将支持另一个系统中存在产品价格的变更&lt;span lang=&quot;EN-US&quot;&gt;&amp;mdash;&lt;/span&gt;总线需要能够理解能够处理和批准变更的权限系统或方法。这些规则可能涉及到复杂性或隐私限制，禁止它们直接在总线上存在。在&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 4&lt;/span&gt;，一个企业可以支持一套步骤或任务，在一个特殊的创建、读取、更新和删除任务被允许之前这些步骤或任务必须遵守。工作流自动化经常用来支持发生在总线上的事件或活动的授权。但是变更管理远远不仅仅是工作流：它可以包括基于逻辑的流程和基于人的决策。变更管理的存在可以支持动态业务，允许变更。举例说明，在&lt;span lang=&quot;EN-US&quot;&gt; 911&lt;/span&gt;之前，任何人都可以在美国国内的航空公司运载货物。没有规定以外的其他某种形式的鉴定和付款方式。&lt;span lang=&quot;EN-US&quot;&gt;911&lt;/span&gt;之后，美国联邦航空协会&lt;span lang=&quot;EN-US&quot;&gt;(FAA)&lt;/span&gt;指导建立了一个更加全面的规定，指示一个人是否被允许运载货物。在这个特殊的例子中，要求各个系统都部署&lt;span lang=&quot;EN-US&quot;&gt;FAA&lt;/span&gt;对托运人的要求是不现实的。部署一个规则管理系统，为所有的系统&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;包括&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;总线&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;集中托运人批准规则，更加容易实现&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;也更现实&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;。集中数据定义和标准化在&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 2&lt;/span&gt;就已经引入，与&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 4&lt;/span&gt;的集中规则管理相比，相对简单。业务流程越复杂、业务流程越多，对总线的需求就越多，以便对针对共同数据的跨职能、异构规则进行更好的支持。重要的是&lt;span lang=&quot;EN-US&quot;&gt; MDM Level 4&lt;/span&gt;支持集中规则管理，但是规则本身和相关的处理是可以分开的。换句话说，&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;总线需要保证规则是集中应用的，即便这个规则是在总线外居住的。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan; mso-outline-level: 1;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　&lt;strong&gt;&lt;span lang=&quot;EN-US&quot;&gt;Level 5 &lt;/span&gt;：企业数据集中&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%; mso-pagination: widow-orphan;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　在&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 5 &lt;/span&gt;，总线和相关的主数据被集成到独立的应用中。主数据和应用数据之间没有明显的分隔。他们是一体的。当主数据记录详细资料被修改后，所有应用的相关数据元素都将被更新。这意味着所有的消费应用和源系统访问的是相同的数据实例。这本质上是一个闭环的&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;：所有的应用系统通过统一管理的主数据集成在一起。在这个级别，所有在系统看起来都是事实的同一个版本。操作应用系统和&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;内容是同步的，所以当变更发生时，操作应用系统都将更新。在那些熟悉的&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;架构风格中，持久总线架构，当一个总线更新所有的操作应用系统将体现这种变更，形成改变的直接操作视图。在注册环境中，当数据数据更新时，总线将通过&lt;span lang=&quot;EN-US&quot;&gt;Web&lt;/span&gt;服务连接相关系统应用事务更新。因此，&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 5&lt;/span&gt;提供一个集成的，同步的架构，当一个有权限的系统更新一个数据值时，公司内所有的系统将反映这个变更。系统更新完数据值后不要单选其他系统中相应值的更新：&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;将使这种更新变的透明。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;MsoNormal&quot; style=&quot;margin: 0cm 0cm 0pt; line-height: 150%;&quot;&gt;&lt;span style=&quot;line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 10.5pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;　　从&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 4&lt;/span&gt;到&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 5&lt;/span&gt;意味着&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;功能性不是在一个应用内被特殊设计或编码的。这还意味着主数据传播和供应不需要源系统专门的开发或支持。所有的应用清楚的知道他们并不拥有或控制主数据。他们仅仅使用数据来支持他们自己的功能和流程。由于&lt;span lang=&quot;EN-US&quot;&gt;MDM&lt;/span&gt;总线和支持的&lt;span lang=&quot;EN-US&quot;&gt;IT&lt;/span&gt;基础架构，所有的应用可以访问主参考数据。一个公司在完成&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 5&lt;/span&gt;后将使他们所有的应用连在一起&lt;span lang=&quot;EN-US&quot;&gt;&amp;mdash;&lt;/span&gt;既包括操作的也包括分析的&lt;span lang=&quot;EN-US&quot;&gt;&amp;mdash;&lt;/span&gt;所有访问主数据是透明的。举例说明，当一个客户更新她的状态&lt;span lang=&quot;EN-US&quot;&gt;&amp;mdash;&lt;/span&gt;不要管注册该变更的系统&lt;span lang=&quot;EN-US&quot;&gt;&amp;mdash;&lt;/span&gt;数据变更将被广播到所有的应用平台&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;因此一致起来&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 5&lt;/span&gt;是把数据概念作为一种&lt;span lang=&quot;EN-US&quot;&gt;service&lt;/span&gt;来实现。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 5&lt;/span&gt;保证了一个一致的主数据主题域企业映像。定义&lt;span lang=&quot;EN-US&quot;&gt;&amp;ldquo;&lt;/span&gt;客户&lt;span lang=&quot;EN-US&quot;&gt;&amp;rdquo;&lt;/span&gt;和其他应用接受客户主数据业务规则变化实际上是一回事。&lt;span lang=&quot;EN-US&quot;&gt;MDM Level 5&lt;/span&gt;移走了主数据的最后一个障碍：统一采用数据定义、授权使用和变更传播&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;
            &lt;div&gt;
                作者：xiong2009 发表于2009-8-17 10:52:00 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/4454597&quot;&gt;原文链接&lt;/a&gt;
            &lt;/div&gt;
            &lt;div&gt;
            阅读：769 评论：0 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/4454597#comments&quot; target=&quot;_blank&quot;&gt;查看评论&lt;/a&gt;
            &lt;/div&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/602964766/xiong2009/feedsky/s.gif?r=http://blog.csdn.net/xiong2009/article/details/4454597&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><pubDate>Mon, 17 Aug 2009 10:52:00 +0800</pubDate><author>xiong2009</author><guid isPermaLink="false">http://blog.csdn.net/xiong2009/article/details/4454597</guid><dc:creator>xiong2009</dc:creator><fs:srclink>http://blog.csdn.net/xiong2009/article/details/4454597</fs:srclink><fs:srcfeed>http://blog.csdn.net/xiong2009/Rss.aspx</fs:srcfeed><fs:itemid>feedsky/xiong2009/~1212304/602964766/1227063</fs:itemid></item><item><title>[原]PowerDesigner中概念数据模型2</title><link>http://blog.csdn.net/xiong2009/article/details/1830131</link><description>&lt;p&gt;&lt;span style=&quot;FONT-SIZE: 10pt&quot;&gt;目标：&lt;br /&gt;本节主要介绍数据项、新增数据项、数据项的唯一性代码选项和重用选项等。&lt;br /&gt;&lt;br /&gt;一、数据项&lt;br /&gt;数据项（Data Item）是信息存储的最小单位，它可以附加在实体上作为实体的属性。&lt;br /&gt;注意：模型中允许存在没有附加至任何实体上的数据项。&lt;br /&gt;&lt;br /&gt;二、新建数据项&lt;br /&gt;1）使用&amp;ldquo;Model&amp;rdquo;---&amp;gt; Data Items 菜单，在打开的窗口中显示已有的数据项的列表，点击 &amp;ldquo;Add a Row&amp;rdquo;按钮，创建一个新数据项，如图所示&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_14.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;2）当然您可以继续设置具体数据项的Code、DataType、Length等等信息。这里就不再详细说明了。&lt;br /&gt;&lt;br /&gt;三、数据项的唯一性代码选项和重用选项&lt;br /&gt;使用Tools---&amp;gt;Model Options-&amp;gt;Model Settings。在Data Item组框中定义数据项的唯一性代码选项(Unique Code)与重用选项（Allow Reuse）。&lt;br /&gt;注意：&lt;br /&gt;如果选择Unique Code复选框 ，每个数据项在同一个命名空间有唯一的代码，而选择Allow reuse ，一个数据项可以充当多个实体的属性。&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_15.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;四、在实体中添加数据项&lt;br /&gt;1）双击一个实体符号，打开该实体的属性窗口。&lt;br /&gt;2）单击Attributes选项卡，打开如下图所示窗口&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_16.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;注意：&lt;br /&gt;Add a DataItem 与 Reuse a DataItem的区别在于&lt;br /&gt;Add a DataItem 情况下，选择一个已经存在的数据项，系统会自动复制所选择的数据项。如果您设置了UniqueCode选项，那系统在复制过程中，新数据项的Code会自动生成一个唯一的号码，否则与所选择的数据项完全一致。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Reuse a DataItem情况下，只引用不新增，就是引用那些已经存在的数据项，作为新实体的数据项。&lt;br /&gt;&lt;br /&gt;------------------------------------------------------------------------------------------&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;FONT-SIZE: 10pt&quot;&gt;&lt;span style=&quot;FONT-SIZE: 10pt&quot;&gt;目标：本节主要介绍联系的定义及使用。&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;FONT-SIZE: 10pt&quot;&gt;&lt;strong&gt;&amp;nbsp;一、&amp;nbsp;联系&lt;/strong&gt;&lt;br /&gt;联系（Relationship）是指实体集这间或实体集内部实例之间的连接。&lt;br /&gt;&lt;br /&gt;&amp;nbsp;实体之间可以通过联系来相互关联。与实体和实体集对应，联系也可以分为联系和联系集，联系集是实体集之间的联系，联系是实体之间的联系，联系是具有方向性的。联系和联系集在含义明确的情况之下均可称为联系。&lt;br /&gt;&lt;br /&gt;&amp;nbsp;按照实体类型中实例之间的数量对应关系，通常可将联系分为4类，即一对一（ONE&amp;nbsp;TO ONE）联系、一对多（ONE TO MANY）联系、多对一（MANY TO ONE）联系和多对多联系（MANY TO MANY）。&lt;/p&gt;
&lt;p style=&quot;FONT-SIZE: 10pt&quot;&gt;&lt;strong&gt;&amp;nbsp;二、&amp;nbsp;建立联系&lt;/strong&gt;&lt;br /&gt;在CDM工具选项板中除了公共的工具外，还包括如下图所示的其它对象产生工具。&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_17.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&amp;nbsp;在图形窗口中创建两个实体后，单击&amp;ldquo;实体间建立联系&amp;rdquo;工具，单击一个实体，在按下鼠标左键的同时把光标拖至别一个实体上并释放鼠标左键，这样就在两个实体间创建了联系，右键单击图形窗口，释放Relationship工具。如下图所示&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_18.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;三、&amp;nbsp;四种基本的联系&lt;br /&gt;&lt;/strong&gt;即一对一（ONE&amp;nbsp;TO ONE）联系、一对多（ONE TO MANY）联系、多对一（MANY TO ONE）联系和多对多联系（MANY TO MANY）。如图所示&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_19.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;strong&gt;四、&amp;nbsp;其他几类特殊联系&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;除了4种基本的联系之外，实体集与实体集之间还存在标定联系（Identify Relationship）、非标定联系（Non-Identify RelationShip）和递归联系（Recursive Relationship）。&lt;br /&gt;&lt;br /&gt;&lt;em&gt;&lt;strong&gt;标定联系：&lt;/strong&gt;&lt;br /&gt;&lt;/em&gt;每个实体类型都有自己的标识符，如果两个实体集之间发生联系，其中一个实体类型的标识符进入另一个实体类型并与该实体类型中的标识符共同组成其标识符时，这种联系则称为标定联系，也叫依赖联系。反之称为非标定联系，也叫非依赖联系。&lt;br /&gt;&lt;span style=&quot;COLOR: #ff0000&quot;&gt;&amp;nbsp;注意：&lt;br /&gt;在非标定联系中，一个实体集中的部分实例依赖于另一个实例集中的实例，在这种依赖联系中，每个实体必须至少有一个标识符。而在标定联系中，一个实体集中的全部实例完全依赖于另个实体集中的实例，在这种依赖联系中一个实体必须至少有一个标识符，而另一个实体却可以没有自己的标识符。没有标识符的实体用它所依赖的实体的标识符作为自己的标识符。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;换句话来理解，在标定联系中，一个实体（选课）依赖 一个实体（学生），那么（学生）实体必须至少有一个标识符，而（选课）实体可以没有自己的标识符，没有标标识符的实体可以用实体（学生）的标识符作为自己的标识符。&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_20.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;FONT-SIZE: 10pt&quot;&gt;&lt;em&gt;&lt;strong&gt;&amp;nbsp;递归联系：&lt;/strong&gt;&lt;br /&gt;&lt;/em&gt;递归联系是实体集内部实例之间的一种联系，通常形象地称为自反联系。同一实体类型中不同实体集之间的联系也称为递归联系。&lt;br /&gt;&lt;br /&gt;例如：在&amp;ldquo;职工&amp;rdquo;实体集中存在很多的职工，这些职工之间必须存在一种领导与被领导的关系。又如&amp;ldquo;学生&amp;rdquo;实体信中的实体包含&amp;ldquo;班长&amp;rdquo;子实体集与&amp;ldquo;普通学生&amp;rdquo;子实体集，这两个子实体集之间的联系就是一种递归联系。创建递归联系时，只需要单击&amp;ldquo;实体间建立联系&amp;rdquo;工具从实体的一部分拖至该实体的别一个部分即可。如图&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_21.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;五、&amp;nbsp;定义联系的特性&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;在两个实体间建立了联系后，双击联系线，打开联系特性窗口，如图所示。&lt;br /&gt;&lt;img height=&quot;490&quot; src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_22.jpg&quot; width=&quot;522&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&amp;nbsp;六、&amp;nbsp;定义联系的角色名&lt;br /&gt;&lt;/strong&gt;在联系的两个方向上各自包含有一个分组框，其中的参数只对这个方向起作用，Role Name为角色名，描述该方向联系的作用，一般用一个动词或动宾组表。&lt;br /&gt;如：&amp;ldquo;学生 to 课目&amp;nbsp;&amp;rdquo; 组框中应该填写&amp;ldquo;拥有&amp;rdquo;，而在&amp;ldquo;课目To 学生&amp;rdquo;组框中填写&amp;ldquo;属于&amp;rdquo;。（在此只是举例说明，可能有些用词不太合理）。&lt;/p&gt;
&lt;p style=&quot;FONT-SIZE: 10pt&quot;&gt;&lt;strong&gt;七、&amp;nbsp;定义联系的强制性&lt;/strong&gt;&lt;br /&gt;Mandatory 表洋这个方向联系的强制关系。选中这个复选框，则在联系线上产生一个联系线垂直的竖线。不选择这个复选框则表示联系这个方向上是可选的，在联系线上产生一个小圆圈。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;八、&amp;nbsp;有关联系的基数&lt;/strong&gt;&lt;br /&gt;联系具有方向性，每个方向上都有一个基数。&lt;br /&gt;&lt;br /&gt;举例，&lt;br /&gt;&amp;ldquo;系&amp;rdquo;与&amp;ldquo;学生&amp;rdquo;两个实体之间的联系是一对多联系，换句话说&amp;ldquo;学生&amp;rdquo;和&amp;ldquo;系&amp;rdquo;之间的联系是多对一联系。而且一个学生必须属于一个系，并且只能属于一个系，不能属于零个系，所以从&amp;ldquo;学生&amp;rdquo;实体至&amp;ldquo;系&amp;rdquo;实体的基数为&amp;ldquo;1,1&amp;rdquo;，从联系的另一方向考虑，一个系可以拥有多个学生，也可以没有任何学生，即零个学生，所以该方向联系的基数就为&amp;ldquo;0,n&amp;rdquo;,如图所示&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_23.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;/p&gt;
            &lt;div&gt;
                作者：xiong2009 发表于2007-10-17 23:40:00 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1830131&quot;&gt;原文链接&lt;/a&gt;
            &lt;/div&gt;
            &lt;div&gt;
            阅读：513 评论：0 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1830131#comments&quot; target=&quot;_blank&quot;&gt;查看评论&lt;/a&gt;
            &lt;/div&gt;</description><pubDate>Wed, 17 Oct 2007 23:40:00 +0800</pubDate><author>xiong2009</author><guid isPermaLink="false">http://blog.csdn.net/xiong2009/article/details/1830131</guid><dc:creator>xiong2009</dc:creator><fs:srclink>http://blog.csdn.net/xiong2009/article/details/1830131</fs:srclink><fs:srcfeed>http://blog.csdn.net/xiong2009/Rss.aspx</fs:srcfeed><fs:itemid>feedsky/xiong2009/~1212304/602964767/1227063</fs:itemid></item><item><title>[原]PowerDesigner中概念数据模型1</title><link>http://blog.csdn.net/xiong2009/article/details/1830126</link><description>&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一、概念数据模型概述&lt;br /&gt;&lt;/strong&gt;数据模型是现实世界中数据特征的抽象。数据模型应该满足三个方面的要求：&lt;br /&gt;1）能够比较真实地模拟现实世界&lt;br /&gt;2）容易为人所理解&lt;br /&gt;3）便于计算机实现&lt;br /&gt;&lt;br /&gt;概念数据模型也称信息模型，它以实体－联系(Entity-RelationShip,简称E-R)理论为基础，并对这一理论进行了扩充。它从用户的观点出发对信息进行建模，主要用于数据库的概念级设计。&lt;br /&gt;&lt;br /&gt;通常人们先将现实世界抽象为概念世界，然后再将概念世界转为机器世界。换句话说，就是先将现实世界中的客观对象抽象为实体(Entity)和联系(Relationship),它并不依赖于具体的计算机系统或某个DBMS系统，这种模型就是我们所说的CDM;然后再将CDM转换为计算机上某个DBMS所支持的数据模型，这样的模型就是物理数据模型,即PDM。&lt;br /&gt;&lt;br /&gt;CDM是一组严格定义的模型元素的集合，这些模型元素精确地描述了系统的&lt;u&gt;静态特性、动态特性以及完整性约束条件&lt;/u&gt;等，其中包括了&lt;u&gt;数据结构、数据操作和完整性约束&lt;/u&gt;三部分。&lt;br /&gt;1）数据结构表达为实体和属性;&lt;br /&gt;2）数据操作表达为实体中的记录的插入、删除、修改、查询等操作;&lt;br /&gt;3）完整性约束表达为数据的自身完整性约束（如数据类型、检查、规则等）和数据间的参照完整性约束（如联系、继承联系等）;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;二、实体、属性及标识符的定义&lt;/strong&gt;&lt;br /&gt;实体（Entity），也称为实例，对应现实世界中可区别于其他对象的&amp;ldquo;事件&amp;rdquo;或&amp;ldquo;事物&amp;rdquo;。例如，学校中的每个学生，医院中的每个手术。&lt;br /&gt;每个实体都有用来描述实体特征的一组性质，称之为属性，一个实体由若干个属性来描述。如学生实体可由学号、姓名、性别、出生年月、所在系别、入学年份等属性组成。&lt;br /&gt;&lt;br /&gt;实体集（Entity Set）是具体相同类型及相同性质实体的集合。例如学校所有学生的集合可定义为&amp;ldquo;学生&amp;rdquo;实体集，&amp;ldquo;学生&amp;rdquo;实体集中的每个实体均具有学号、姓名、性别、出生年月、所在系别、入学年份等性质。&lt;br /&gt;&lt;br /&gt;实体类型（Entity Type）是实体集中每个实体所具有的共同性质的集合，例如&amp;ldquo;患者&amp;rdquo;实体类型为：患者｛门诊号，姓名，性别，年龄，身份证号.............｝。实体是实体类型的一个实例，在含义明确的情况下，实体、实体类型通常互换使用。&lt;br /&gt;&lt;br /&gt;实体类型中的每个实体包含唯一标识它的一个或一组属性，这些属性称为实体类型的标识符（Identifier），如&amp;ldquo;学号&amp;rdquo;是学生实体类型的标识符，&amp;ldquo;姓名&amp;rdquo;、&amp;ldquo;出生日期&amp;rdquo;、&amp;ldquo;信址&amp;rdquo;共同组成&amp;ldquo;公民&amp;rdquo;实体类型的标识符。&lt;br /&gt;&lt;br /&gt;有些实体类型可以有几组属性充当标识符，选定其中一组属性作为实体类型的主标识符，其他的作为次标识符。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;三、实体、属性及标识符的表达&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_01.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－&lt;/p&gt;
&lt;p&gt;目标：&lt;br /&gt;下节主要介绍PowerDesigner概念数据模型以及实体、属性创建。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;一、新建概念数据模型&lt;/strong&gt;&lt;br /&gt;1）选择File--&amp;gt;New,弹出如图所示对话框，选择CDM模型（即概念数据模型）建立模型。&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_02.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;2）完成概念数据模型的创建。以下图示，对当前的工作空间进行简单介绍。（以后再更详细说明）&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_03.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;3）选择新增的CDM模型，右击，在弹出的菜单中选择&amp;ldquo;Properties&amp;rdquo;属性项，弹出如图所示对话框。在&amp;ldquo;General&amp;rdquo;标签里可以输入所建模型的名称、代码、描述、创建者、版本以及默认的图表等等信息。在&amp;ldquo;Notes&amp;rdquo;标签里可以输入相关描述及说明信息。当然再有更多的标签，可以点击 &amp;quot;More&amp;gt;&amp;gt;&amp;quot;按钮，这里就不再进行详细解释。&lt;br /&gt;&lt;img height=&quot;403&quot; src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_04.jpg&quot; width=&quot;522&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;二、创建新实体&lt;/strong&gt;&lt;br /&gt;1）在CDM的图形窗口中，单击工具选项版上的Entity工具，再单击图形窗口的空白处，在单击的位置就出现一个实体符号。点击Pointer工具或右击鼠标，释放Entitiy工具。如图所示&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_05.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;2）双击刚创建的实体符号，打开下列图标窗口，在此窗口&amp;ldquo;General&amp;rdquo;标签中可以输入实体的名称、代码、描述等信息。&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_06.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;三、添加实体属性&lt;/strong&gt;&lt;br /&gt;1）在上述窗口的&amp;ldquo;Attribute&amp;rdquo;选项标签上可以添加属性，如下图所示。&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_07.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;注意：&lt;br /&gt;数据项中的&amp;ldquo;添加属性&amp;rdquo;和&amp;ldquo;重用已有数据项&amp;rdquo;这两项功能与模型中Data Item的Unique code 和Allow reuse选项有关。&lt;br /&gt;P列表示该属性是否为主标识符;D列表示该属性是否在图形窗口中显示;M列表示该属性是否为强制的，即该列是否为空值。&lt;br /&gt;&lt;br /&gt;如果一个实体属性为强制的，那么， 这个属性在每条记录中都必须被赋值，不能为空。&lt;/p&gt;
&lt;p style=&quot;FONT-SIZE: 10pt&quot;&gt;2）在上图所示窗口中，点击插入属性按钮，弹出属性对话框，如下图所示。&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_08.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p style=&quot;FONT-SIZE: 10pt&quot;&gt;注意：这里涉及到域的概念，即一种标准的数据结构，它可应用至数据项或实体的属性上。在以下的教程中将另立章节详细说明。&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------------------&lt;/p&gt;
&lt;p style=&quot;FONT-SIZE: 10pt&quot;&gt;&lt;span style=&quot;FONT-SIZE: 10pt&quot;&gt;目标：&lt;br /&gt;本节主要介绍属性的标准检查约束、如何定义属性的附加检查。&lt;br /&gt;&lt;br /&gt;一、定义属性的标准检查约束&lt;br /&gt;标准检查约束是一组确保属性有效的表达式。在实体属性的特性窗口，打开如图所示的检查选项卡。&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_09.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;在这个选项卡可以定义属性的标准检查约束，窗口中每项的参数的含义，如下&lt;br /&gt;
&lt;table style=&quot;BORDER-RIGHT: #000000 1px solid; PADDING-RIGHT: 1px; BORDER-TOP: #000000 1px solid; PADDING-LEFT: 1px; PADDING-BOTTOM: 1px; MARGIN: 1px; BORDER-LEFT: #000000 1px solid; WIDTH: 577px; PADDING-TOP: 1px; BORDER-BOTTOM: #000000 1px solid; BORDER-COLLAPSE: collapse; HEIGHT: 52px&quot; cellspacing=&quot;0&quot; cellpadding=&quot;3&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt; WIDTH: 107px; HEIGHT: 25px&quot;&gt;参数&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;说明&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;Minimum&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;属性可接受的最小数&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;Maximum&amp;nbsp;&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;属性可接受的最大数&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;Default&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;属性不赋值时，系统提供的默认值&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;Unit&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;单位，如公里、吨、元&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;Format&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;属性的数据显示格式&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;Lowercase&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;属性的赋值全部变为小写字母&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;Uppercase&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;属性的赋值全部变为大写字母&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;Cannot modify&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;该属性一旦赋值不能再修改&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;List Of Values&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;属性赋值列表，除列表中的值，不能有其他的值&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;Label&lt;/td&gt;
            &lt;td style=&quot;FONT-SIZE: 10pt&quot;&gt;属性列表值的标签&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;二、定义属性的附加检查&lt;br /&gt;当Standard checks 或Rules 不能满足检查的要求时，可以在Additional Checks选项卡的Server子页上，通过SQL语句中使用%MINMAX%、%LISTVAL%、%RULES%、%UPPER%、%LOWER%几个变量来定义Standard和Rule,如图所示&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_10.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;%MINMAX%、%LISTVAL%、%UPPER%、%LOWER%&lt;br /&gt;在Standard Check中定义的Minimum 和Maximum、List values 、uppervalues、lowervalues&lt;br /&gt;&lt;br /&gt;%RULES%&lt;br /&gt;在Rules特性窗口Expression选项卡中定义的有效性规则表达式&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;---------------------------------------------------------------------------&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;FONT-SIZE: 10pt&quot;&gt;目标：&lt;br /&gt;本节主要介绍如何定义实体的主、次标识符。&lt;br /&gt;&lt;br /&gt;一、标识符&lt;br /&gt;标识符是实体中一个或多个属性的集合，可用来唯一标识实体中的一个实例。要强调的是，CDM中的标识符等价于PDM中的主键或候选键。&lt;br /&gt;每个实体都必须至少有一个标识符。如果实体只有一个标识符，则它为实体的主标识符。如果实体有多个标识符，则其中一个被指定为主标识符，其余的标识符就是次标识符了。&lt;br /&gt;&lt;br /&gt;二、如果定义主、次标识符&lt;br /&gt;1）选择某个实体双击弹出实体的属性对话框。在Identifiers选项卡上可以进行实体标识符的定义。如下图所示&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_11.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;2）选择第一行&amp;ldquo;主标识符&amp;rdquo;，点击属性按钮或双击第一行&amp;ldquo;主标识符&amp;rdquo;，弹出属性对话框，如图所示&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_12.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;FONT-SIZE: 10pt&quot;&gt;3）选择&amp;quot;Attributes&amp;quot;选项卡，再点击&amp;ldquo;Add Attributes&amp;rdquo;工具，弹出如图所示窗口，选择某个属性作为标识符就行了。&lt;br /&gt;&lt;img src=&quot;http://www.cnblogs.com/images/cnblogs_com/yxonline/PD_13.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
            &lt;div&gt;
                作者：xiong2009 发表于2007-10-17 23:36:00 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1830126&quot;&gt;原文链接&lt;/a&gt;
            &lt;/div&gt;
            &lt;div&gt;
            阅读：714 评论：0 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1830126#comments&quot; target=&quot;_blank&quot;&gt;查看评论&lt;/a&gt;
            &lt;/div&gt;</description><pubDate>Wed, 17 Oct 2007 23:36:00 +0800</pubDate><author>xiong2009</author><guid isPermaLink="false">http://blog.csdn.net/xiong2009/article/details/1830126</guid><dc:creator>xiong2009</dc:creator><fs:srclink>http://blog.csdn.net/xiong2009/article/details/1830126</fs:srclink><fs:srcfeed>http://blog.csdn.net/xiong2009/Rss.aspx</fs:srcfeed><fs:itemid>feedsky/xiong2009/~1212304/602964768/1227063</fs:itemid></item><item><title>[原]appFuse2.x第八篇--Maven2</title><link>http://blog.csdn.net/xiong2009/article/details/1762618</link><description>Knowledge of &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://maven.apache.org/&quot;&gt;Maven&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; is not required to use AppFuse because the tutorials explain how to use it. If you're interested in learning Maven in-depth, please download the book &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.mergere.com/m2book_download.jsp&quot;&gt;Better Builds with Maven&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; or &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.sonatype.com/book/&quot;&gt;Maven: The Definitive Guide&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; (&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.sonatype.com/MavenTheDefinitiveGuide.zip&quot;&gt;zip&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;). Both books are free - the first requires registration, the second is available without registration.
&lt;p&gt;For a brief introduction to Maven see &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://today.java.net/pub/a/today/2007/03/01/building-web-applications-with-maven-2.html&quot;&gt;Building Web Applications with Maven 2&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; or &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.javaworld.com/javaworld/jw-05-2006/jw-0529-maven.html&quot;&gt;The Maven 2 POM demystified&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. Other articles are available from the &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://maven.apache.org/articles.html&quot;&gt;Articles on Maven&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; page.&lt;/p&gt;
&lt;p&gt;See &lt;a title=&quot;Maven Plugins&quot; href=&quot;http://appfuse.org/display/APF/Maven+Plugins&quot;&gt;Maven Plugins&lt;/a&gt; for information on plugins used in AppFuse. &lt;/p&gt;
&lt;p&gt;Below is a list of commonly-used helpful Maven commands.&lt;/p&gt;
&lt;div style=&quot;MARGIN-LEFT: 30px; MARGIN-RIGHT: 30px&quot;&gt;
&lt;table class=&quot;confluenceTable&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;th class=&quot;confluenceTh&quot;&gt;Command&lt;/th&gt;
            &lt;th class=&quot;confluenceTh&quot;&gt;Description&lt;/th&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn clean&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Deletes all files in target directory or directories (for multi-module projects)&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn jetty:run-war&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Packages and deploys your application to Jetty, reachable at &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://localhost:8080/&quot;&gt;http://localhost:8080&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn -Dcargo.wait=true&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Packages and deploys your application to active Cargo profile (Tomcat 5.5.x by default), reachable at &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://localhost:8080/yourapp-version&quot;&gt;http://localhost:8080/yourapp-version&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn test&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Runs all tests in &lt;em&gt;src/test/java&lt;/em&gt;. Use &amp;quot;-Dtest=ClassName&amp;quot; (not fully-qualified) to run individual tests. &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&amp;nbsp;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Use &lt;strong&gt;-Dsurefire.useFile=false&lt;/strong&gt; if you want to see test failures in your console (like Ant) and &lt;strong&gt;-Dmaven.surefire.debug&lt;/strong&gt; if you want to open a debugger on port 5005 w/ suspend=y.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn package&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Creates a WAR or JAR depending on your project type&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn integration-test&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Runs UI tests in Tomcat using Cargo&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn install&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Installs generated artifacts in your local repository&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn site&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Creates project site and reports&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn -U&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Checks for updated plugins and downloads if they exist&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn -o&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Work offline&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;&lt;strong&gt;mvn --help&lt;/strong&gt;&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;See full list of optional commands&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;Maven2-Antvs.Maven&quot;&gt;&lt;/a&gt;Ant vs. Maven &lt;a name=&quot;Maven2-anttomaven&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you used AppFuse 1.x in the past and have taken the time to memorize its useful &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://raibledesigns.com/wiki/AppFuseAntTasks.html&quot;&gt;Ant commands&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;, the following table should help you convert to using Maven. &lt;/p&gt;
&lt;div style=&quot;MARGIN-LEFT: 30px; MARGIN-RIGHT: 30px&quot;&gt;
&lt;table class=&quot;confluenceTable&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;th class=&quot;confluenceTh&quot;&gt;Ant command&lt;/th&gt;
            &lt;th class=&quot;confluenceTh&quot;&gt;Maven command&lt;/th&gt;
            &lt;th class=&quot;confluenceTh&quot;&gt;Description&lt;/th&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;ant setup-db&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;mvn hibernate3:hbm2ddl dbunit:operation&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Creates and populates your database&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;ant test-all&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;mvn integration-test&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Runs unit and integration tests&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;ant clean&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;mvn clean&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Deletes the target directory&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;ant compile&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;mvn compile&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Compiles all source files&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;ant war&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;mvn package&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Creates a WAR file&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;ant deploy&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;mvn jetty:run-war&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Deploys a WAR to embedded instance of Jetty and starts it&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;ant test-dao&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;mvn test -Dtest=*DaoTest&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Runs all DAO tests&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;ant test-service&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;mvn test -Dtest=*ManagerTest&lt;/td&gt;
            &lt;td class=&quot;confluenceTd&quot;&gt;Runs all Manager tests&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;Maven2-InstallingalocalMavenRepository&quot;&gt;&lt;/a&gt;Installing a local Maven Repository &lt;a name=&quot;Maven2-localrepo&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you're using Maven 2 in your organization on multiple projects, it's often a good idea to setup a local Maven repository on your intranet. There's a few different strategies for doing this:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.jfrog.org/sites/artifactory/latest/introduction.html&quot;&gt;Artifactory&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; - a Maven2 proxy repository based on JSR-170. Started with maven-proxy's codebase. See &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.theserverside.com/tt/articles/article.tss?l=SettingUpMavenRepository&quot;&gt;Setting up a Maven repository with Artifactory&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; for installation instructions. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.pdark.de/dsmp/&quot;&gt;Dead Simple Maven Proxy&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; - DSMP is a proxy. It can be used as a repository server but it's main purposs it to act as a filter when Maven accesses the internet. If you need a repository server, use Archiva. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://maven.apache.org/archiva/&quot;&gt;Maven Archiva&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; - still under development. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://maven-proxy.codehaus.org/&quot;&gt;Maven Proxy&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; - See Sanjiv's blog entry titled &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.jroller.com/page/sjivan?entry=using_maven_proxy_to_setup&quot;&gt;Using maven-proxy to setup an internal maven repository&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; for more information. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://proximity.abstracthorizon.org/&quot;&gt;Proximity&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; - Proximity functions somewhere between http-proxy and proactive-mirror. One of its primary uses is as Java web application to serve as a Maven proxy on your company's intranet. &lt;/li&gt;
&lt;/ul&gt;
&amp;lt;!-- &amp;lt;rdf:RDF xmlns:rdf=&amp;quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&amp;quot; xmlns:dc=&amp;quot;http://purl.org/dc/elements/1.1/&amp;quot; xmlns:trackback=&amp;quot;http:/&amp;nbsp;
            &lt;div&gt;
                作者：xiong2009 发表于2007-8-28 19:17:00 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1762618&quot;&gt;原文链接&lt;/a&gt;
            &lt;/div&gt;
            &lt;div&gt;
            阅读：1432 评论：0 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1762618#comments&quot; target=&quot;_blank&quot;&gt;查看评论&lt;/a&gt;
            &lt;/div&gt;</description><pubDate>Tue, 28 Aug 2007 19:17:00 +0800</pubDate><author>xiong2009</author><guid isPermaLink="false">http://blog.csdn.net/xiong2009/article/details/1762618</guid><dc:creator>xiong2009</dc:creator><fs:srclink>http://blog.csdn.net/xiong2009/article/details/1762618</fs:srclink><fs:srcfeed>http://blog.csdn.net/xiong2009/Rss.aspx</fs:srcfeed><fs:itemid>feedsky/xiong2009/~1212304/602964769/1227063</fs:itemid></item><item><title>[原]appFuse2.x第七篇--Maven Plugins</title><link>http://blog.csdn.net/xiong2009/article/details/1762611</link><description>There are a number of Maven Plugins that AppFuse uses to simplify the development process (listed in alphabetical order).
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin&quot;&gt;AppFuse Maven Plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;: This plugin is a replacement for AppGen in AppFuse 1.x. It's used for code generation, as well as other AppFuse-related tasks. See the list below for current enhancement ideas. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://cargo.codehaus.org/Maven2+plugin&quot;&gt;Cargo Maven Plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;: Used to start and stop containers before and after running integration tests (i.e. with Canoo WebTest or Selenium). &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://mojo.codehaus.org/dbunit-maven-plugin/&quot;&gt;DbUnit Maven Plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;: This plugin is a wrapper around &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://dbunit.sourceforge.net/&quot;&gt;DbUnit&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; and is used to populate the database with sample data before running tests. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://mojo.codehaus.org/maven-hibernate3/hibernate3-maven-plugin/&quot;&gt;Hibernate3 Maven Plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;: Used to create the database schema when using Hibernate or JPA for the DAO framework. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.mortbay.org/maven-plugin/index.html&quot;&gt;Maven Jetty Plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;: Used to run an embedded Jetty instance from Maven. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://static.appfuse.org/plugins/maven-warpath-plugin/&quot;&gt;Maven WarPath Plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;: Used to provide features to Maven so WARs can have dependencies. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://mojo.codehaus.org/native2ascii-maven-plugin/&quot;&gt;Native2Ascii Maven Plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;: Converts i18n bundles from native to ascii format. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://mojo.codehaus.org/sql-maven-plugin/&quot;&gt;SQL Maven Plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;: Used to create the database schema when using iBATIS for the DAO framework. &lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://mojo.codehaus.org/tomcat-maven-plugin/&quot;&gt;Tomcat Maven Plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;: Similar to the Maven Jetty Plugin - can start an embedded Tomcat instance to deploy your project or manage a remote instance. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more plugins, see &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://maven.apache.org/plugins/index.html&quot;&gt;available Maven plugins&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; and the &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://mojo.codehaus.org/&quot;&gt;Maven 2 Plugins Project&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; (also known as &lt;em&gt;Mojo&lt;/em&gt;).&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;MavenPlugins-AbouttheAppFuseMavenPlugin&quot;&gt;&lt;/a&gt;About the AppFuse Maven Plugin&lt;/h2&gt;
&lt;p&gt;This release marks the first release of the AppFuse Maven Plugin (AMP). This plugin currently does two things: 1) code generation for CRUD and 2) allows you to convert your project to use AppFuse's source instead of using its binary dependencies. For more information on this plugin, see &lt;span class=&quot;nobr&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin&quot;&gt;http://static.appfuse.org/plugins/appfuse-maven-plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generating CRUD with AMP&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In the &lt;a title=&quot;Release Notes 2.0 M5&quot; href=&quot;http://appfuse.org/display/APF/Release+Notes+2.0+M5&quot;&gt;AppFuse 2.0 M5 release&lt;/a&gt;, you can run the following command to generate CRUD screens/classes for a POJO:&lt;/p&gt;
&lt;div class=&quot;preformatted&quot;&gt;
&lt;div class=&quot;preformattedContent&quot;&gt;
&lt;pre&gt;appfuse:gen -Dentity=Name
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you don't specify the entity name, you're prompted for it. After generating the code, you can install it using:&lt;/p&gt;
&lt;div class=&quot;preformatted&quot;&gt;
&lt;div class=&quot;preformattedContent&quot;&gt;
&lt;pre&gt;appfuse:install -Dentity=Name
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Your entity must be defined in your hibernate.cfg.xml file for this to work. In a modular project, these commands must be run in the &amp;quot;core&amp;quot; and &amp;quot;web&amp;quot; modules. The plugin is smart enough to figure out when it should/should not generate stuff based on the packaging type (jar vs. war). In a future release, we hope to combine &amp;quot;gen&amp;quot; and &amp;quot;install&amp;quot; into a single command. &lt;/p&gt;
&lt;p&gt;There's also a goal that allows you to generate model objects from database tables:&lt;/p&gt;
&lt;div class=&quot;preformatted&quot;&gt;
&lt;div class=&quot;preformattedContent&quot;&gt;
&lt;pre&gt;appfuse:gen-model
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This goal does not install the generated files into your source tree, so you'll need to manually copy it. If you want to generate CRUD for the object, you'll also want to add it to your hibernate.cfg.xml.&lt;/p&gt;
&lt;p&gt;We hope to combine these commands in a future release.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Installing AppFuse's source into your project&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The good news is creating an &amp;quot;old style&amp;quot; project is now pretty easy. If you create a new project using 2.0-m5-SNAPSHOT, you can now use:&lt;/p&gt;
&lt;div class=&quot;preformatted&quot;&gt;
&lt;div class=&quot;preformattedContent&quot;&gt;
&lt;pre&gt;mvn appfuse:full-source
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This goal will convert your project to use all of AppFuse's source and remove all dependencies on AppFuse. Known issues with &amp;quot;full-source&amp;quot; include:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;It only supports basic archetypes. It will likely only take a couple of hours to add modular project support, so this feature will be in the next release. &lt;/li&gt;
    &lt;li&gt;It doesn't do package renaming. We plan to add this as part of the next release. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What the full-source plugin does:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Exports all sources from Subversion into your project. It reads the dao.framework and web.framework properties to determine what you need. &lt;/li&gt;
    &lt;li&gt;Removes warpath plugin from pom.xml. &lt;/li&gt;
    &lt;li&gt;Calculates dependencies by reading pom.xml files form the various AppFuse modules. It replaces your dependencies with these new ones. The order of the dependencies added is alphabetical based on groupId. &lt;/li&gt;
    &lt;li&gt;Reads properties from the root AppFuse pom.xml and adds the ones that don't exist to your project. Since these are stored in a java.util.Properties, I was unable to sort them alphabetically. &lt;/li&gt;
&lt;/ol&gt;
&lt;!--
&lt;rdf:RDF xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;
xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot;
xmlns:trackback=&quot;http://madskills.com/public/xml/rss/module/trackback/&quot;&gt;
&lt;rdf:Description
rdf:about=&quot;http://appfuse.org/display/APF/Maven+Plugins&quot;
dc:identifier=&quot;http://appfuse.org/display/APF/Maven+Plugins&quot;
dc:title=&quot;Maven Plugins&quot;
trackback:ping=&quot;http://appfuse.org/rpc/trackback/99&quot; /&gt;
&lt;/rdf:RDF&gt;
--&gt;&amp;nbsp;
&lt;p&gt;Goals available:&lt;/p&gt;
&lt;table class=&quot;bodyTable&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr class=&quot;a&quot;&gt;
            &lt;th&gt;Goal&lt;/th&gt;
            &lt;th&gt;Description&lt;/th&gt;
        &lt;/tr&gt;
        &lt;tr class=&quot;b&quot;&gt;
            &lt;td&gt;&lt;a href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin/gen-core-mojo.html&quot;&gt;appfuse:gen-core&lt;/a&gt;&lt;/td&gt;
            &lt;td&gt;Generates Java classes for DAOs and Managers from set of annotated POJOs&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr class=&quot;a&quot;&gt;
            &lt;td&gt;&lt;a href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin/gen-web-mojo.html&quot;&gt;appfuse:gen-web&lt;/a&gt;&lt;/td&gt;
            &lt;td&gt;Generates Java classes for DAOs and Managers from set of annotated POJOs&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr class=&quot;b&quot;&gt;
            &lt;td&gt;&lt;a href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin/gen-mojo.html&quot;&gt;appfuse:gen&lt;/a&gt;&lt;/td&gt;
            &lt;td&gt;Generates Java classes from set of annotated POJOs&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr class=&quot;a&quot;&gt;
            &lt;td&gt;&lt;a href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin/hbmtemplate-mojo.html&quot;&gt;appfuse:hbmtemplate&lt;/a&gt;&lt;/td&gt;
            &lt;td&gt;Generic exporter that can be controlled by a user provided template or class.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr class=&quot;b&quot;&gt;
            &lt;td&gt;&lt;a href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin/gen-model-mojo.html&quot;&gt;appfuse:gen-model&lt;/a&gt;&lt;/td&gt;
            &lt;td&gt;Generates Java classes from set of *.hbm.xml files&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr class=&quot;a&quot;&gt;
            &lt;td&gt;&lt;a href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin/install-mojo.html&quot;&gt;appfuse:install&lt;/a&gt;&lt;/td&gt;
            &lt;td&gt;This mojo is used to &amp;quot;install&amp;quot; generated artifacts (Java files, XML files) into an AppFuse project.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr class=&quot;b&quot;&gt;
            &lt;td&gt;&lt;a href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin/full-source-mojo.html&quot;&gt;appfuse:full-source&lt;/a&gt;&lt;/td&gt;
            &lt;td&gt;This mojo is used to &amp;quot;install&amp;quot; source artifacts from Subversion into an AppFuse project.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
            &lt;div&gt;
                作者：xiong2009 发表于2007-8-28 19:07:00 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1762611&quot;&gt;原文链接&lt;/a&gt;
            &lt;/div&gt;
            &lt;div&gt;
            阅读：1762 评论：0 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1762611#comments&quot; target=&quot;_blank&quot;&gt;查看评论&lt;/a&gt;
            &lt;/div&gt;</description><pubDate>Tue, 28 Aug 2007 19:07:00 +0800</pubDate><author>xiong2009</author><guid isPermaLink="false">http://blog.csdn.net/xiong2009/article/details/1762611</guid><dc:creator>xiong2009</dc:creator><fs:srclink>http://blog.csdn.net/xiong2009/article/details/1762611</fs:srclink><fs:srcfeed>http://blog.csdn.net/xiong2009/Rss.aspx</fs:srcfeed><fs:itemid>feedsky/xiong2009/~1212304/602964770/1227063</fs:itemid></item><item><title>[原]appFuse2.x第六篇--Using Struts 2</title><link>http://blog.csdn.net/xiong2009/article/details/1756525</link><description>&lt;p&gt;This tutorial will show you how to create master/detail screens with &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://struts.apache.org/&quot;&gt;Struts 2&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. The list (master) screen will have the ability to sort columns, as well as page 25 records at a time. The form (detail) screen will use an elegant CSS form layout (courtesy of &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://wufoo.com/&quot;&gt;Wufoo&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;). You will also configure client and server-side validation to improve your users' experience.&lt;/p&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;This tutorial assumes you've created a project with the &lt;strong&gt;appfuse-basic-struts&lt;/strong&gt; archetype and have already completed the &lt;a title=&quot;Persistence&quot; href=&quot;http://www.appfuse.org/display/APF/Persistence&quot;&gt;Persistence&lt;/a&gt; and &lt;a title=&quot;Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services&quot;&gt;Services&lt;/a&gt; tutorials. If you're using the &lt;strong&gt;appfuse-modular-struts&lt;/strong&gt; archetype, please morph your mind into using the &lt;em&gt;web&lt;/em&gt; module as the root directory. If you created your project with a different web framework than Struts, you're likely to be confused and nothing will work in this tutorial. &lt;img class=&quot;emoticon&quot; height=&quot;20&quot; alt=&quot;&quot; width=&quot;20&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/wink.gif&quot; /&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;&lt;a name=&quot;UsingStruts2-TableofContents&quot;&gt;&lt;/a&gt;Table of Contents&lt;/h3&gt;
&lt;p&gt;&lt;img style=&quot;FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://www.appfuse.org/download/attachments/36/struts2-logo.png' _fcksavedurl='http://www.appfuse.org/download/attachments/36/struts2-logo.png',sizingMethod='scale'); WIDTH: 256px; HEIGHT: 86px&quot; alt=&quot;&quot; hspace=&quot;5&quot; src=&quot;http://www.appfuse.org/images/border/spacer.gif&quot; align=&quot;right&quot; border=&quot;0&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;a title=&quot;introduction on Using Struts 2&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Struts+2#UsingStruts2-introduction&quot;&gt;Introduction to Struts 2&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;actiontest on Using Struts 2&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Struts+2#UsingStruts2-actiontest&quot;&gt;Create a PersonActionTest&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;action on Using Struts 2&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Struts+2#UsingStruts2-action&quot;&gt;Create a PersonAction that will fetch people&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;listview on Using Struts 2&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Struts+2#UsingStruts2-listview&quot;&gt;Create personList.jsp to show search results&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;actionmethods on Using Struts 2&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Struts+2#UsingStruts2-actionmethods&quot;&gt;Modify PersonActionTest and PersonAction for edit(), save() and delete() methods&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;formview on Using Struts 2&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Struts+2#UsingStruts2-formview&quot;&gt;Create personForm.jsp to edit a person&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;validation on Using Struts 2&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Struts+2#UsingStruts2-validation&quot;&gt;Configure Validation&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;webtest on Using Struts 2&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Struts+2#UsingStruts2-webtest&quot;&gt;Create a Canoo WebTest to test browser-like actions&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;menu on Using Struts 2&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Struts+2#UsingStruts2-menu&quot;&gt;Add link to menu&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;table class=&quot;infoMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/information.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Source Code&lt;/strong&gt;&lt;br /&gt;
            &lt;p&gt;The code for this tutorial is located in the &amp;quot;tutorial-struts2&amp;quot; module of the &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://code.google.com/p/appfuse-demos/&quot;&gt;appfuse-demos&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; project on Google Code. Use the following command to check it out from Subversion:&lt;/p&gt;
            &lt;div class=&quot;preformatted&quot;&gt;
            &lt;div class=&quot;preformattedContent&quot;&gt;
            &lt;pre&gt;svn checkout http://appfuse-demos.googlecode.com/svn/trunk/tutorial-struts2
&lt;/pre&gt;
            &lt;/div&gt;
            &lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;a name=&quot;UsingStruts2-IntroductiontoStruts2&quot;&gt;&lt;/a&gt;Introduction to Struts 2&lt;/h2&gt;
&lt;p&gt;&lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://struts.apache.org/2.x/&quot;&gt;Struts 2&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; (formerly WebWork) is a web framework designed with simplicity in mind. It's built on top of XWork, which is a generic command framework. XWork also has an IoC container, but it isn't as full-featured as Spring and won't be covered in this section. Struts 2 controllers are called &lt;em&gt;Actions&lt;/em&gt;, mainly because they must implement the &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://struts.apache.org/2.x/struts2-core/apidocs/com/opensymphony/xwork2/Action.html&quot;&gt;Action&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; interface. The &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://struts.apache.org/2.x/struts2-core/apidocs/com/opensymphony/xwork2/ActionSupport.html&quot;&gt;ActionSupport&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; class implements this interface, and it is most common parent class for Struts 2 actions.&lt;/p&gt;
&lt;p&gt;The figure below shows how Struts 2 fits into a web application's architecture.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;&lt;img style=&quot;FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://www.appfuse.org/download/attachments/36/struts2-spring.png' _fcksavedurl='http://www.appfuse.org/download/attachments/36/struts2-spring.png',sizingMethod='scale'); WIDTH: 595px; HEIGHT: 291px&quot; height=&quot;291&quot; alt=&quot;&quot; src=&quot;http://www.appfuse.org/images/border/spacer.gif&quot; width=&quot;595&quot; border=&quot;0&quot; /&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Struts 2 actions typically contain methods for accessing model properties and methods for returning strings. These strings are matched with &amp;quot;result&amp;quot; names in a &lt;em&gt;struts.xml&lt;/em&gt; configuration file. Actions typically have a single &lt;em&gt;execute()&lt;/em&gt; method, but you can easily add multiple methods and control execution using URLs and button names. &lt;/p&gt;
&lt;p&gt;Struts 2 uses interceptors to intercept the request and response process. This is much like Servlet Filters, except you can talk directly to the action. Struts 2 uses interceptors in the framework itself. A number of them initialize the Action, prepare it for population, set parameters on it and handle any conversion errors.&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;UsingStruts2-CreateaPersonActionTest&quot;&gt;&lt;/a&gt;Create a PersonActionTest &lt;a name=&quot;UsingStruts2-actiontest&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Testing is an important part of any application, and testing a Struts application is easier than most. The generic command pattern provided by XWork doesn't depend on the Servlet API at all. This makes it easy to use JUnit to test your Actions.&lt;/p&gt;
&lt;p&gt;Create a &lt;tt&gt;PersonActionTest.java&lt;/tt&gt; class in &lt;em&gt;src/test/java/**/webapp/action&lt;/em&gt;. &lt;/p&gt;
&lt;style type=&quot;text/css&quot;&gt;

@import url( /download/resources/confluence.ext.code:code/shStyles.css );&lt;/style&gt;&lt;style type=&quot;text/css&quot;&gt;

.code TEXTAREA {
	PADDING-RIGHT: 0px! important; PADDING-LEFT: 0px! important; PADDING-BOTTOM: 0px! important; PADDING-TOP: 0px! important
}
.code INPUT {
	PADDING-RIGHT: 0px! important; PADDING-LEFT: 0px! important; PADDING-BOTTOM: 0px! important; PADDING-TOP: 0px! important
}&lt;/style&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shCore.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushCSharp.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushPhp.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushJScript.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushVb.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushSql.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushXml.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushShell.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushDelphi.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushPython.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushJava.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.webapp.action; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;com.opensymphony.xwork2.ActionSupport; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.service.GenericManager; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.model.Person; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.webapp.action.BaseActionTestCase; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonActionTest&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BaseActionTestCase&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonAction&amp;nbsp;action; &lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;preprocessor&quot;&gt;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;preprocessor&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Override &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onSetUpBeforeTransaction()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;super.onSetUpBeforeTransaction(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action&amp;nbsp;=&amp;nbsp;new&amp;nbsp;PersonAction(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GenericManager&amp;nbsp;personManager&amp;nbsp;=&amp;nbsp;(GenericManager)&amp;nbsp;applicationContext.getBean(&lt;span class=&quot;string&quot;&gt;&amp;quot;personManager&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action.setPersonManager(personManager); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;add&amp;nbsp;a&amp;nbsp;test&amp;nbsp;person&amp;nbsp;to&amp;nbsp;the&amp;nbsp;database &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Person&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.setFirstName(&lt;span class=&quot;string&quot;&gt;&amp;quot;Jack&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.setLastName(&lt;span class=&quot;string&quot;&gt;&amp;quot;Raible&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;personManager.save(person); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testSearch()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertEquals(action.list(),&amp;nbsp;ActionSupport.SUCCESS); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertTrue(action.getPersons().size()&amp;nbsp;&amp;gt;=&amp;nbsp;1); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; cols=&quot;65&quot; name=&quot;newcodemacro&quot;&gt;package org.appfuse.tutorial.webapp.action;
import com.opensymphony.xwork2.ActionSupport;
import org.appfuse.service.GenericManager;
import org.appfuse.tutorial.model.Person;
import org.appfuse.webapp.action.BaseActionTestCase;
public class PersonActionTest extends BaseActionTestCase {
private PersonAction action;
@Override
protected void onSetUpBeforeTransaction() throws Exception {
super.onSetUpBeforeTransaction();
action = new PersonAction();
GenericManager personManager = (GenericManager) applicationContext.getBean(&amp;quot;personManager&amp;quot;);
action.setPersonManager(personManager);
// add a test person to the database
Person person = new Person();
person.setFirstName(&amp;quot;Jack&amp;quot;);
person.setLastName(&amp;quot;Raible&amp;quot;);
personManager.save(person);
}
public void testSearch() throws Exception {
assertEquals(action.list(), ActionSupport.SUCCESS);
assertTrue(action.getPersons().size() &amp;gt;= 1);
}
}&lt;/textarea&gt;&lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;This class won't compile yet; you must first create the &lt;tt&gt;PersonAction&lt;/tt&gt; class. &lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;UsingStruts2-CreateaPersonActionthatwillfetchpeople&quot;&gt;&lt;/a&gt;Create a PersonAction that will fetch people &lt;a name=&quot;UsingStruts2-action&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Create a &lt;tt&gt;PersonAction.java&lt;/tt&gt; class (that extends AppFuse's &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://static.appfuse.org/appfuse-struts/xref/org/appfuse/webapp/action/BaseAction.html&quot;&gt;BaseAction&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;) in &lt;em&gt;src/main/java/**/webapp/action&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.webapp.action; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.webapp.action.BaseAction; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.model.Person; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.service.GenericManager; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;java.util.List; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonAction&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BaseAction&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;GenericManager&amp;lt;Person,&amp;nbsp;Long&amp;gt;&amp;nbsp;personManager; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;List&amp;nbsp;persons; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;setPersonManager(GenericManager&amp;lt;Person,&amp;nbsp;Long&amp;gt;&amp;nbsp;personManager)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.personManager&amp;nbsp;=&amp;nbsp;personManager; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;List&amp;nbsp;getPersons()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;persons; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;list()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;persons&amp;nbsp;=&amp;nbsp;personManager.getAll(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;SUCCESS; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;package org.appfuse.tutorial.webapp.action;
import org.appfuse.webapp.action.BaseAction;
import org.appfuse.tutorial.model.Person;
import org.appfuse.service.GenericManager;
import java.util.List;
public class PersonAction extends BaseAction {
private GenericManager&amp;lt;Person, Long&amp;gt; personManager;
private List persons;
public void setPersonManager(GenericManager&amp;lt;Person, Long&amp;gt; personManager) {
this.personManager = personManager;
}
public List getPersons() {
return persons;
}
public String list() {
persons = personManager.getAll();
return SUCCESS;
}
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Struts 2 actions are typically both the controller and the model. In this example, the &lt;tt&gt;list()&lt;/tt&gt; method acts as the controller, and the &lt;tt&gt;getPersons()&lt;/tt&gt; method retrieves data from the model. This simplification of the MVC paradigm makes this web framework very easy to program with.&lt;/p&gt;
&lt;p&gt;Run the &lt;tt&gt;PersonActionTest&lt;/tt&gt; using your IDE or &lt;strong&gt;mvn test -Dtest=PersonActionTest&lt;/strong&gt;. &lt;/p&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Zero Configuration&lt;/strong&gt;&lt;br /&gt;
            &lt;p&gt;Struts' &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://raibledesigns.com/rd/entry/zero_configuration_in_struts_2&quot;&gt;Zero Configuration&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; feature is turned on by default. If you want to configure your Actions as Spring beans, you can do that by using class=&amp;quot;beanId&amp;quot; in your Action definition, and then defining the bean in applicationContext.xml. Otherwise, they will automatically be wired up by name with Spring dependencies. All you need to do is add a setter to your Action to get a Spring bean injected into it.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;a name=&quot;UsingStruts2-CreatepersonList.jsptoshowsearchresults&quot;&gt;&lt;/a&gt;Create personList.jsp to show search results &lt;a name=&quot;UsingStruts2-listview&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Create a &lt;em&gt;src/main/webapp/WEB-INF/pages/personList.jsp&lt;/em&gt; page to display the list of people:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;%@&amp;nbsp;include&amp;nbsp;file=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/common/taglibs.jsp&amp;quot;&lt;/span&gt;&lt;span&gt;%&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;head&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;title&amp;gt;&amp;lt;fmt:message&amp;nbsp;key=&lt;span class=&quot;string&quot;&gt;&amp;quot;personList.title&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&amp;lt;/title&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;meta&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;heading&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;content=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;lt;fmt:message&amp;nbsp;key='personList.heading'/&amp;gt;&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/head&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;c:set&amp;nbsp;var=&lt;span class=&quot;string&quot;&gt;&amp;quot;buttons&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;input&amp;nbsp;type=&lt;span class=&quot;string&quot;&gt;&amp;quot;button&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;style=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;margin-right:&amp;nbsp;5px&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onclick=&lt;span class=&quot;string&quot;&gt;&amp;quot;location.href='&amp;lt;c:url&amp;nbsp;value=&amp;quot;&lt;/span&gt;&lt;span&gt;/editPerson.html&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/&amp;gt;'&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value=&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;lt;fmt:message&amp;nbsp;key=&amp;quot;&lt;/span&gt;&lt;span&gt;button.add&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/&amp;gt;&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;input&amp;nbsp;type=&lt;span class=&quot;string&quot;&gt;&amp;quot;button&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;onclick=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;location.href='&amp;lt;c:url&amp;nbsp;value=&amp;quot;&lt;/span&gt;&lt;span&gt;/mainMenu.html&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/&amp;gt;'&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value=&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;lt;fmt:message&amp;nbsp;key=&amp;quot;&lt;/span&gt;&lt;span&gt;button.done&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/&amp;gt;&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/c:set&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;c:out&amp;nbsp;value=&lt;span class=&quot;string&quot;&gt;&amp;quot;${buttons}&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;escapeXml=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;s:set&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;persons&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;value=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;persons&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;scope=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;request&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;display:table&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;persons&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;table&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;requestURI=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;id=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;personList&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;export=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;pagesize=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;25&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;display:column&amp;nbsp;property=&lt;span class=&quot;string&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;sortable=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;href=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;editPerson.html&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;paramId=&lt;span class=&quot;string&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;paramProperty=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;titleKey=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;person.id&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;display:column&amp;nbsp;property=&lt;span class=&quot;string&quot;&gt;&amp;quot;firstName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;sortable=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;titleKey=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;person.firstName&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;display:column&amp;nbsp;property=&lt;span class=&quot;string&quot;&gt;&amp;quot;lastName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;sortable=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;titleKey=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;person.lastName&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;display:setProperty&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;paging.banner.item_name&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;value=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;person&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;display:setProperty&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;paging.banner.items_name&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;value=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;people&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;display:setProperty&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;export.excel.filename&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;value=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Person&amp;nbsp;List.xls&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;display:setProperty&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;export.csv.filename&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;value=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Person&amp;nbsp;List.csv&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;display:setProperty&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;export.pdf.filename&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;value=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Person&amp;nbsp;List.pdf&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/display:table&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;c:out&amp;nbsp;value=&lt;span class=&quot;string&quot;&gt;&amp;quot;${buttons}&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;escapeXml=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;script&amp;nbsp;type=&lt;span class=&quot;string&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;highlightTableRows(&lt;span class=&quot;string&quot;&gt;&amp;quot;personList&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/script&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;%@ include file=&amp;quot;/common/taglibs.jsp&amp;quot;%&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;&amp;lt;fmt:message key=&amp;quot;personList.title&amp;quot;/&amp;gt;&amp;lt;/title&amp;gt;
&amp;lt;meta name=&amp;quot;heading&amp;quot; content=&amp;quot;&amp;lt;fmt:message key='personList.heading'/&amp;gt;&amp;quot;/&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;c:set var=&amp;quot;buttons&amp;quot;&amp;gt;
&amp;lt;input type=&amp;quot;button&amp;quot; style=&amp;quot;margin-right: 5px&amp;quot;
onclick=&amp;quot;location.href='&amp;lt;c:url value=&amp;quot;/editPerson.html&amp;quot;/&amp;gt;'&amp;quot;
value=&amp;quot;&amp;lt;fmt:message key=&amp;quot;button.add&amp;quot;/&amp;gt;&amp;quot;/&amp;gt;
&amp;lt;input type=&amp;quot;button&amp;quot; onclick=&amp;quot;location.href='&amp;lt;c:url value=&amp;quot;/mainMenu.html&amp;quot;/&amp;gt;'&amp;quot;
value=&amp;quot;&amp;lt;fmt:message key=&amp;quot;button.done&amp;quot;/&amp;gt;&amp;quot;/&amp;gt;
&amp;lt;/c:set&amp;gt;
&amp;lt;c:out value=&amp;quot;${buttons}&amp;quot; escapeXml=&amp;quot;false&amp;quot; /&amp;gt;
&amp;lt;s:set name=&amp;quot;persons&amp;quot; value=&amp;quot;persons&amp;quot; scope=&amp;quot;request&amp;quot;/&amp;gt;
&amp;lt;display:table name=&amp;quot;persons&amp;quot; class=&amp;quot;table&amp;quot; requestURI=&amp;quot;&amp;quot; id=&amp;quot;personList&amp;quot; export=&amp;quot;true&amp;quot; pagesize=&amp;quot;25&amp;quot;&amp;gt;
&amp;lt;display:column property=&amp;quot;id&amp;quot; sortable=&amp;quot;true&amp;quot; href=&amp;quot;editPerson.html&amp;quot;
paramId=&amp;quot;id&amp;quot; paramProperty=&amp;quot;id&amp;quot; titleKey=&amp;quot;person.id&amp;quot;/&amp;gt;
&amp;lt;display:column property=&amp;quot;firstName&amp;quot; sortable=&amp;quot;true&amp;quot; titleKey=&amp;quot;person.firstName&amp;quot;/&amp;gt;
&amp;lt;display:column property=&amp;quot;lastName&amp;quot; sortable=&amp;quot;true&amp;quot; titleKey=&amp;quot;person.lastName&amp;quot;/&amp;gt;
&amp;lt;display:setProperty name=&amp;quot;paging.banner.item_name&amp;quot; value=&amp;quot;person&amp;quot;/&amp;gt;
&amp;lt;display:setProperty name=&amp;quot;paging.banner.items_name&amp;quot; value=&amp;quot;people&amp;quot;/&amp;gt;
&amp;lt;display:setProperty name=&amp;quot;export.excel.filename&amp;quot; value=&amp;quot;Person List.xls&amp;quot;/&amp;gt;
&amp;lt;display:setProperty name=&amp;quot;export.csv.filename&amp;quot; value=&amp;quot;Person List.csv&amp;quot;/&amp;gt;
&amp;lt;display:setProperty name=&amp;quot;export.pdf.filename&amp;quot; value=&amp;quot;Person List.pdf&amp;quot;/&amp;gt;
&amp;lt;/display:table&amp;gt;
&amp;lt;c:out value=&amp;quot;${buttons}&amp;quot; escapeXml=&amp;quot;false&amp;quot; /&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
highlightTableRows(&amp;quot;personList&amp;quot;);
&amp;lt;/script&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;The most important line in this file is just above the &amp;lt;display:table&amp;gt; tag. This is the &lt;tt&gt;&amp;lt;s:set&amp;gt;&lt;/tt&gt; tag. This tag calls &lt;tt&gt;PersonAction.getPersons()&lt;/tt&gt; and sets the resulting List into the request scope, where the &amp;lt;display:table&amp;gt; tag can grab it. This is necessary because the Display Tag doesn't have any knowledge of the ValueStack used by Struts 2.&lt;/p&gt;
&lt;p&gt;Open the &lt;tt&gt;struts.xml&lt;/tt&gt; file in the &lt;em&gt;src/main/resources&lt;/em&gt; directory. Define an &amp;lt;action&amp;gt; (at the bottom of this file) and set its class attribute to match the fully-qualified class name of the PersonAction class.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;action&amp;nbsp;name=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;persons&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.tutorial.webapp.action.PersonAction&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;method=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;list&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;result&amp;gt;/WEB-INF/pages/personList.jsp&amp;lt;/result&amp;gt;&amp;nbsp; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/action&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;action name=&amp;quot;persons&amp;quot; class=&amp;quot;org.appfuse.tutorial.webapp.action.PersonAction&amp;quot; method=&amp;quot;list&amp;quot;&amp;gt;
&amp;lt;result&amp;gt;/WEB-INF/pages/personList.jsp&amp;lt;/result&amp;gt;
&amp;lt;/action&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;The default result type is &amp;quot;dispatcher&amp;quot; and its name is &amp;quot;success&amp;quot;. This configured result type simply forwards you to the &lt;tt&gt;personList.jsp&lt;/tt&gt; file when &amp;quot;success&amp;quot; is returned from &lt;tt&gt;PersonAction.list()&lt;/tt&gt;. Other result types include redirect and chain. Redirect performs a client-side redirect and chain forwards you to another action. For a full list of result types, see Struts 2's &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://struts.apache.org/2.x/docs/result-types.html&quot;&gt;Result Types documentation&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The &amp;quot;method&amp;quot; attribute of this action has a &lt;tt&gt;list&lt;/tt&gt; attribute, which calls the &lt;tt&gt;list()&lt;/tt&gt; method when the &amp;quot;persons.html&amp;quot; URL is invoked. If you exclude the method attribute, it calls the &lt;tt&gt;execute()&lt;/tt&gt; method.&lt;/p&gt;
&lt;p&gt;Open &lt;em&gt;src/main/resources/ApplicationResources.properties&lt;/em&gt; and add i18n keys/values for the various &amp;quot;person&amp;quot; properties:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;#&amp;nbsp;--&amp;nbsp;person&amp;nbsp;form&amp;nbsp;-- &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;person.id=Id &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;person.firstName=First&amp;nbsp;Name &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;person.lastName=Last&amp;nbsp;Name &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;person.added=Person&amp;nbsp;has&amp;nbsp;been&amp;nbsp;added&amp;nbsp;successfully. &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;person.updated=Person&amp;nbsp;has&amp;nbsp;been&amp;nbsp;updated&amp;nbsp;successfully. &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;person.deleted=Person&amp;nbsp;has&amp;nbsp;been&amp;nbsp;deleted&amp;nbsp;successfully. &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;#&amp;nbsp;--&amp;nbsp;person&amp;nbsp;list&amp;nbsp;page&amp;nbsp;-- &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;personList.title=Person&amp;nbsp;List &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;personList.heading=Persons &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;#&amp;nbsp;--&amp;nbsp;person&amp;nbsp;detail&amp;nbsp;page&amp;nbsp;-- &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;personDetail.title=Person&amp;nbsp;Detail &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;personDetail.heading=Person&amp;nbsp;Information&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;# -- person form --
person.id=Id
person.firstName=First Name
person.lastName=Last Name
person.added=Person has been added successfully.
person.updated=Person has been updated successfully.
person.deleted=Person has been deleted successfully.
# -- person list page --
personList.title=Person List
personList.heading=Persons
# -- person detail page --
personDetail.title=Person Detail
personDetail.heading=Person Information&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Run &lt;strong&gt;mvn jetty:run-war&lt;/strong&gt; and open &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://localhost:8080/persons.html&quot;&gt;http://localhost:8080/persons.html&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; in your browser. Login with &lt;strong&gt;admin&lt;/strong&gt;/&lt;strong&gt;admin&lt;/strong&gt; and you should see a screen similar to the figure below.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;&lt;img style=&quot;FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://www.appfuse.org/download/attachments/36/personList.png' _fcksavedurl='http://www.appfuse.org/download/attachments/36/personList.png',sizingMethod='scale'); WIDTH: 500px; HEIGHT: 333px&quot; height=&quot;333&quot; alt=&quot;&quot; src=&quot;http://www.appfuse.org/images/border/spacer.gif&quot; width=&quot;500&quot; border=&quot;1&quot; /&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Security settings for AppFuse specify that all *.html url-patterns should be protected (except for /signup.html and /passwordHint.html). This guarantees that clients must go through an Action to get to a JSP (or at least the ones in &lt;em&gt;WEB-INF/pages&lt;/em&gt;). &lt;/p&gt;
&lt;table class=&quot;infoMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/information.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;CSS Customization&lt;/strong&gt;&lt;br /&gt;If you want to customize the CSS for a particular page, you can add &amp;lt;body id=&amp;quot;pageName&amp;quot;/&amp;gt; to the top of the file. This will be slurped up by SiteMesh and put into the final page. You can then customize your CSS on a page-by-page basis using something like the following:
            &lt;div class=&quot;preformatted&quot;&gt;
            &lt;div class=&quot;preformattedContent&quot;&gt;
            &lt;pre&gt;body#pageName element.class { background-color: blue } 
&lt;/pre&gt;
            &lt;/div&gt;
            &lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;a name=&quot;UsingStruts2-ModifyPersonActionTestandPersonActionforedit%28%29%2Csave%28%29anddelete%28%29method&quot;&gt;&lt;/a&gt;Modify PersonActionTest and PersonAction for edit(), save() and delete() method &lt;a name=&quot;UsingStruts2-actionmethods&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To create the detail screen, add &lt;tt&gt;edit()&lt;/tt&gt;, &lt;tt&gt;save()&lt;/tt&gt;, and &lt;tt&gt;delete()&lt;/tt&gt; methods to the PersonAction class. Before doing this, create tests for these methods. &lt;/p&gt;
&lt;p&gt;Open &lt;em&gt;src/test/java/**/webapp/action/PersonActionTest.java&lt;/em&gt; and add test methods for edit, save, and delete operations:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testEdit()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;edit...&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action.setId(1L); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertNull(action.getPerson()); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertEquals(&lt;span class=&quot;string&quot;&gt;&amp;quot;success&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;action.edit()); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertNotNull(action.getPerson()); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertFalse(action.hasActionErrors()); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testSave()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MockHttpServletRequest&amp;nbsp;request&amp;nbsp;=&amp;nbsp;new&amp;nbsp;MockHttpServletRequest(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ServletActionContext.setRequest(request); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action.setId(1L); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertEquals(&lt;span class=&quot;string&quot;&gt;&amp;quot;success&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;action.edit()); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertNotNull(action.getPerson()); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;update&amp;nbsp;last&amp;nbsp;name&amp;nbsp;and&amp;nbsp;save &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action.getPerson().setLastName(&lt;span class=&quot;string&quot;&gt;&amp;quot;Updated&amp;nbsp;Last&amp;nbsp;Name&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertEquals(&lt;span class=&quot;string&quot;&gt;&amp;quot;input&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;action.save()); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertEquals(&lt;span class=&quot;string&quot;&gt;&amp;quot;Updated&amp;nbsp;Last&amp;nbsp;Name&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;action.getPerson().getLastName()); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertFalse(action.hasActionErrors()); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertFalse(action.hasFieldErrors()); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertNotNull(request.getSession().getAttribute(&lt;span class=&quot;string&quot;&gt;&amp;quot;messages&amp;quot;&lt;/span&gt;&lt;span&gt;)); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testRemove()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MockHttpServletRequest&amp;nbsp;request&amp;nbsp;=&amp;nbsp;new&amp;nbsp;MockHttpServletRequest(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ServletActionContext.setRequest(request); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action.setDelete(&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Person&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.setId(2L); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action.setPerson(person); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertEquals(&lt;span class=&quot;string&quot;&gt;&amp;quot;success&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;action.delete()); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertNotNull(request.getSession().getAttribute(&lt;span class=&quot;string&quot;&gt;&amp;quot;messages&amp;quot;&lt;/span&gt;&lt;span&gt;)); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;public void testEdit() throws Exception {
log.debug(&amp;quot;testing edit...&amp;quot;);
action.setId(1L);
assertNull(action.getPerson());
assertEquals(&amp;quot;success&amp;quot;, action.edit());
assertNotNull(action.getPerson());
assertFalse(action.hasActionErrors());
}
public void testSave() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
ServletActionContext.setRequest(request);
action.setId(1L);
assertEquals(&amp;quot;success&amp;quot;, action.edit());
assertNotNull(action.getPerson());
// update last name and save
action.getPerson().setLastName(&amp;quot;Updated Last Name&amp;quot;);
assertEquals(&amp;quot;input&amp;quot;, action.save());
assertEquals(&amp;quot;Updated Last Name&amp;quot;, action.getPerson().getLastName());
assertFalse(action.hasActionErrors());
assertFalse(action.hasFieldErrors());
assertNotNull(request.getSession().getAttribute(&amp;quot;messages&amp;quot;));
}
public void testRemove() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
ServletActionContext.setRequest(request);
action.setDelete(&amp;quot;&amp;quot;);
Person person = new Person();
person.setId(2L);
action.setPerson(person);
assertEquals(&amp;quot;success&amp;quot;, action.delete());
assertNotNull(request.getSession().getAttribute(&amp;quot;messages&amp;quot;));
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;This class will not compile yet because you need to update your &lt;em&gt;src/main/java/**/action/PersonAction.java&lt;/em&gt; class. The cancel and delete properties capture the click of the Cancel and Delete buttons. The &lt;tt&gt;execute()&lt;/tt&gt; method routes the different actions on the form to the appropriate method.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;Person&amp;nbsp;person; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;Long&amp;nbsp;id; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;setId(Long&amp;nbsp;id)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.id&amp;nbsp;=&amp;nbsp;id; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;Person&amp;nbsp;getPerson()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;person; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;setPerson(Person&amp;nbsp;person)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.person&amp;nbsp;=&amp;nbsp;person; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;delete()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;personManager.remove(person.getId()); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;saveMessage(getText(&lt;span class=&quot;string&quot;&gt;&amp;quot;person.deleted&amp;quot;&lt;/span&gt;&lt;span&gt;)); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;SUCCESS; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;edit()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(id&amp;nbsp;!=&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;personManager.get(id); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;SUCCESS; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;save()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(cancel&amp;nbsp;!=&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;cancel&amp;quot;&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(delete&amp;nbsp;!=&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;delete(); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;boolean&lt;/span&gt;&lt;span&gt;&amp;nbsp;isNew&amp;nbsp;=&amp;nbsp;(person.getId()&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;personManager.save(person); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;key&amp;nbsp;=&amp;nbsp;(isNew)&amp;nbsp;?&amp;nbsp;&lt;span class=&quot;string&quot;&gt;&amp;quot;person.added&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;person.updated&amp;quot;&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;saveMessage(getText(key)); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(!isNew)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;INPUT; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;SUCCESS; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;private Person person;
private Long id;
public void setId(Long id) {
this.id = id;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String delete() {
personManager.remove(person.getId());
saveMessage(getText(&amp;quot;person.deleted&amp;quot;));
return SUCCESS;
}
public String edit() {
if (id != null) {
person = personManager.get(id);
} else {
person = new Person();
}
return SUCCESS;
}
public String save() throws Exception {
if (cancel != null) {
return &amp;quot;cancel&amp;quot;;
}
if (delete != null) {
return delete();
}
boolean isNew = (person.getId() == null);
person = personManager.save(person);
String key = (isNew) ? &amp;quot;person.added&amp;quot; : &amp;quot;person.updated&amp;quot;;
saveMessage(getText(key));
if (!isNew) {
return INPUT;
} else {
return SUCCESS;
}
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;If you look at your &lt;tt&gt;PersonActionTest&lt;/tt&gt;, all the tests depend on having a record with id=1 in the database (and testRemove depends on id=2), so let's add those records to our sample data file (src/test/resources/sample-data.xml). Adding it at the bottom should work - order is not important since it (currently) does not relate to any other tables. If you already have this table, make sure the 2nd record exists so &lt;tt&gt;testRemove()&lt;/tt&gt; doesn't fail.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;table&amp;nbsp;name=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;'person'&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;column&amp;gt;id&amp;lt;/column&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;column&amp;gt;first_name&amp;lt;/column&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;column&amp;gt;last_name&amp;lt;/column&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;row&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;1&amp;lt;/value&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;Matt&amp;lt;/value&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;Raible&amp;lt;/value&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/row&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;row&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;2&amp;lt;/value&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;Bob&amp;lt;/value&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;Johnson&amp;lt;/value&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/row&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/table&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;table name='person'&amp;gt;
&amp;lt;column&amp;gt;id&amp;lt;/column&amp;gt;
&amp;lt;column&amp;gt;first_name&amp;lt;/column&amp;gt;
&amp;lt;column&amp;gt;last_name&amp;lt;/column&amp;gt;
&amp;lt;row&amp;gt;
&amp;lt;value&amp;gt;1&amp;lt;/value&amp;gt;
&amp;lt;value&amp;gt;Matt&amp;lt;/value&amp;gt;
&amp;lt;value&amp;gt;Raible&amp;lt;/value&amp;gt;
&amp;lt;/row&amp;gt;
&amp;lt;row&amp;gt;
&amp;lt;value&amp;gt;2&amp;lt;/value&amp;gt;
&amp;lt;value&amp;gt;Bob&amp;lt;/value&amp;gt;
&amp;lt;value&amp;gt;Johnson&amp;lt;/value&amp;gt;
&amp;lt;/row&amp;gt;
&amp;lt;/table&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;DbUnit loads this file before you run any tests, so this record will be available to your Action test. &lt;/p&gt;
&lt;p&gt;Save all your files and run the tests in &lt;tt&gt;PersonActionTest&lt;/tt&gt; using the command &lt;strong&gt;mvn test -Dtest=PersonActionTest&lt;/strong&gt;. &lt;/p&gt;
&lt;span style=&quot;COLOR: green&quot;&gt;BUILD SUCCESSFUL&lt;br clear=&quot;all&quot; /&gt;Total time: 31 seconds&lt;/span&gt;
&lt;h2&gt;&lt;a name=&quot;UsingStruts2-CreatepersonForm.jsptoeditaperson%27sinformation&quot;&gt;&lt;/a&gt;Create personForm.jsp to edit a person's information &lt;a name=&quot;UsingStruts2-formview&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Create a &lt;em&gt;src/main/webapp/WEB-INF/pages/personForm.jsp&lt;/em&gt; page to display the form:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;%@&amp;nbsp;include&amp;nbsp;file=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/common/taglibs.jsp&amp;quot;&lt;/span&gt;&lt;span&gt;%&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;head&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;title&amp;gt;&amp;lt;fmt:message&amp;nbsp;key=&lt;span class=&quot;string&quot;&gt;&amp;quot;personDetail.title&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&amp;lt;/title&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;meta&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;heading&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;content=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;lt;fmt:message&amp;nbsp;key='personDetail.heading'/&amp;gt;&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/head&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;s:form&amp;nbsp;id=&lt;span class=&quot;string&quot;&gt;&amp;quot;personForm&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;action=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;savePerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;method=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;validate=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;s:hidden&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;person.id&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;value=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;%{person.id}&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;s:textfield&amp;nbsp;key=&lt;span class=&quot;string&quot;&gt;&amp;quot;person.firstName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;required=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;cssClass=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;text&amp;nbsp;medium&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;s:textfield&amp;nbsp;key=&lt;span class=&quot;string&quot;&gt;&amp;quot;person.lastName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;required=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;cssClass=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;text&amp;nbsp;medium&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;buttonBar&amp;nbsp;bottom&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;s:submit&amp;nbsp;cssClass=&lt;span class=&quot;string&quot;&gt;&amp;quot;button&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;method=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;save&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;key=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;button.save&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;theme=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;simple&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;c:&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;test=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;${not&amp;nbsp;empty&amp;nbsp;person.id}&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;s:submit&amp;nbsp;cssClass=&lt;span class=&quot;string&quot;&gt;&amp;quot;button&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;method=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;delete&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;key=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;button.delete&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;onclick=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;return&amp;nbsp;confirmDelete('person')&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;theme=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;simple&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/c:&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;s:submit&amp;nbsp;cssClass=&lt;span class=&quot;string&quot;&gt;&amp;quot;button&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;method=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;cancel&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;key=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;button.cancel&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;theme=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;simple&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/li&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/s:form&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;script&amp;nbsp;type=&lt;span class=&quot;string&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Form.focusFirstElement($(&lt;span class=&quot;string&quot;&gt;&amp;quot;personForm&amp;quot;&lt;/span&gt;&lt;span&gt;)); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/script&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;%@ include file=&amp;quot;/common/taglibs.jsp&amp;quot;%&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;&amp;lt;fmt:message key=&amp;quot;personDetail.title&amp;quot;/&amp;gt;&amp;lt;/title&amp;gt;
&amp;lt;meta name=&amp;quot;heading&amp;quot; content=&amp;quot;&amp;lt;fmt:message key='personDetail.heading'/&amp;gt;&amp;quot;/&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;s:form id=&amp;quot;personForm&amp;quot; action=&amp;quot;savePerson&amp;quot; method=&amp;quot;post&amp;quot; validate=&amp;quot;true&amp;quot;&amp;gt;
&amp;lt;s:hidden name=&amp;quot;person.id&amp;quot; value=&amp;quot;%{person.id}&amp;quot;/&amp;gt;
&amp;lt;s:textfield key=&amp;quot;person.firstName&amp;quot; required=&amp;quot;true&amp;quot; cssClass=&amp;quot;text medium&amp;quot;/&amp;gt;
&amp;lt;s:textfield key=&amp;quot;person.lastName&amp;quot; required=&amp;quot;true&amp;quot; cssClass=&amp;quot;text medium&amp;quot;/&amp;gt;
&amp;lt;li class=&amp;quot;buttonBar bottom&amp;quot;&amp;gt;
&amp;lt;s:submit cssClass=&amp;quot;button&amp;quot; method=&amp;quot;save&amp;quot; key=&amp;quot;button.save&amp;quot; theme=&amp;quot;simple&amp;quot;/&amp;gt;
&amp;lt;c:if test=&amp;quot;${not empty person.id}&amp;quot;&amp;gt;
&amp;lt;s:submit cssClass=&amp;quot;button&amp;quot; method=&amp;quot;delete&amp;quot; key=&amp;quot;button.delete&amp;quot; onclick=&amp;quot;return confirmDelete('person')&amp;quot; theme=&amp;quot;simple&amp;quot;/&amp;gt;
&amp;lt;/c:if&amp;gt;
&amp;lt;s:submit cssClass=&amp;quot;button&amp;quot; method=&amp;quot;cancel&amp;quot; key=&amp;quot;button.cancel&amp;quot; theme=&amp;quot;simple&amp;quot;/&amp;gt;
&amp;lt;/li&amp;gt;
&amp;lt;/s:form&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
Form.focusFirstElement($(&amp;quot;personForm&amp;quot;));
&amp;lt;/script&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Struts reduces the amount of HTML you have to write for a form. The &amp;lt;s:form&amp;gt; tag writes the &amp;lt;form&amp;gt; and structure tags for you. The &amp;lt;s:textfield&amp;gt; tag writes the whole row, including the &amp;lt;ul&amp;gt; and &amp;lt;li&amp;gt; tags to hold the input field's label. &lt;/p&gt;
&lt;p&gt;Next, update the &lt;em&gt;src/main/resources/struts.xml&lt;/em&gt; file to include the &amp;quot;editPerson&amp;quot; and &amp;quot;savePerson&amp;quot; actions. &lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;action&amp;nbsp;name=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;editPerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.tutorial.webapp.action.PersonAction&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;method=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;edit&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;result&amp;gt;/WEB-INF/pages/personForm.jsp&amp;lt;/result&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;result&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;error&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;/WEB-INF/pages/personList.jsp&amp;lt;/result&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/action&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;action&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;savePerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.tutorial.webapp.action.PersonAction&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;method=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;save&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;result&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;input&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;/WEB-INF/pages/personForm.jsp&amp;lt;/result&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;result&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;cancel&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;type=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;redirect&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;persons.html&amp;lt;/result&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;result&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;delete&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;type=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;redirect&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;persons.html&amp;lt;/result&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;result&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;success&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;type=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;redirect&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;persons.html&amp;lt;/result&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/action&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;action name=&amp;quot;editPerson&amp;quot; class=&amp;quot;org.appfuse.tutorial.webapp.action.PersonAction&amp;quot; method=&amp;quot;edit&amp;quot;&amp;gt;
&amp;lt;result&amp;gt;/WEB-INF/pages/personForm.jsp&amp;lt;/result&amp;gt;
&amp;lt;result name=&amp;quot;error&amp;quot;&amp;gt;/WEB-INF/pages/personList.jsp&amp;lt;/result&amp;gt;
&amp;lt;/action&amp;gt;
&amp;lt;action name=&amp;quot;savePerson&amp;quot; class=&amp;quot;org.appfuse.tutorial.webapp.action.PersonAction&amp;quot; method=&amp;quot;save&amp;quot;&amp;gt;
&amp;lt;result name=&amp;quot;input&amp;quot;&amp;gt;/WEB-INF/pages/personForm.jsp&amp;lt;/result&amp;gt;
&amp;lt;result name=&amp;quot;cancel&amp;quot; type=&amp;quot;redirect&amp;quot;&amp;gt;persons.html&amp;lt;/result&amp;gt;
&amp;lt;result name=&amp;quot;delete&amp;quot; type=&amp;quot;redirect&amp;quot;&amp;gt;persons.html&amp;lt;/result&amp;gt;
&amp;lt;result name=&amp;quot;success&amp;quot; type=&amp;quot;redirect&amp;quot;&amp;gt;persons.html&amp;lt;/result&amp;gt;
&amp;lt;/action&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Run &lt;strong&gt;mvn jetty:run-war&lt;/strong&gt;, open your browser to &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://localhost:8080/persons.html&quot;&gt;http://localhost:8080/persons.html&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;, and click on the Add button.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;&lt;img style=&quot;FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://www.appfuse.org/download/attachments/36/personForm.png' _fcksavedurl='http://www.appfuse.org/download/attachments/36/personForm.png',sizingMethod='scale'); WIDTH: 500px; HEIGHT: 297px&quot; height=&quot;297&quot; alt=&quot;&quot; src=&quot;http://www.appfuse.org/images/border/spacer.gif&quot; width=&quot;500&quot; border=&quot;1&quot; /&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Fill in the first name and last name fields and click the Save button. This should route you to the list screen, where a success message flashes and the new person displays in the list.&lt;/p&gt;
&lt;table class=&quot;infoMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/information.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Displaying success messages&lt;/strong&gt;&lt;br /&gt;The &lt;em&gt;src/main/webapp/common/messages.jsp&lt;/em&gt; file in AppFuse renders the success message in this screen. This file is included in &lt;em&gt;decorators/default.jsp&lt;/em&gt;. It also handles displaying validation errors:
            &lt;div class=&quot;preformatted&quot;&gt;
            &lt;div class=&quot;preformattedContent&quot;&gt;
            &lt;pre&gt;&amp;lt;s:if test=&amp;quot;hasActionErrors()&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;error&amp;quot; id=&amp;quot;errorMessages&amp;quot;&amp;gt;
      &amp;lt;s:iterator value=&amp;quot;actionErrors&amp;quot;&amp;gt;
        &amp;lt;img src=&amp;quot;&amp;lt;c:url value=&amp;quot;/images/iconWarning.gif&amp;quot;/&amp;gt;&amp;quot;
            alt=&amp;quot;&amp;lt;fmt:message key=&amp;quot;icon.warning&amp;quot;/&amp;gt;&amp;quot; class=&amp;quot;icon&amp;quot; /&amp;gt;
        &amp;lt;s:property escape=&amp;quot;false&amp;quot;/&amp;gt;&amp;lt;br /&amp;gt;
      &amp;lt;/s:iterator&amp;gt;
   &amp;lt;/div&amp;gt;
&amp;lt;/s:if&amp;gt;

&amp;lt;%-- FieldError Messages - usually set by validation rules --%&amp;gt;
&amp;lt;s:if test=&amp;quot;hasFieldErrors()&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;error&amp;quot; id=&amp;quot;errorMessages&amp;quot;&amp;gt;
      &amp;lt;s:iterator value=&amp;quot;fieldErrors&amp;quot;&amp;gt;
          &amp;lt;s:iterator value=&amp;quot;value&amp;quot;&amp;gt;
            &amp;lt;img src=&amp;quot;&amp;lt;c:url value=&amp;quot;/images/iconWarning.gif&amp;quot;/&amp;gt;&amp;quot;
                alt=&amp;quot;&amp;lt;fmt:message key=&amp;quot;icon.warning&amp;quot;/&amp;gt;&amp;quot; class=&amp;quot;icon&amp;quot; /&amp;gt;
             &amp;lt;s:property escape=&amp;quot;false&amp;quot;/&amp;gt;&amp;lt;br /&amp;gt;
          &amp;lt;/s:iterator&amp;gt;
      &amp;lt;/s:iterator&amp;gt;
   &amp;lt;/div&amp;gt;
&amp;lt;/s:if&amp;gt;
&lt;/pre&gt;
            &lt;/div&gt;
            &lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;a name=&quot;UsingStruts2-ConfigureValidation&quot;&gt;&lt;/a&gt;Configure Validation &lt;a name=&quot;UsingStruts2-validation&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Struts 2 allows two types of validation: per-action and model-based. Since you likely want the same rules applied for the person object across different actions, this tutorial will use model-based.&lt;/p&gt;
&lt;p&gt;Create a new file named Person-validation.xml in the &lt;em&gt;src/main/resources/**/model&lt;/em&gt; directory (you'll need to create this directory). It should contain the following XML:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;!DOCTYPE&amp;nbsp;validators&amp;nbsp;PUBLIC&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;-//OpenSymphony&amp;nbsp;Group//XWork&amp;nbsp;Validator&amp;nbsp;1.0.2//EN&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;string&quot;&gt;&amp;quot;http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;validators&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;field&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;person.firstName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;field-validator&amp;nbsp;type=&lt;span class=&quot;string&quot;&gt;&amp;quot;requiredstring&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;message&amp;nbsp;key=&lt;span class=&quot;string&quot;&gt;&amp;quot;errors.required&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/field-validator&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/field&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;field&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;person.lastName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;field-validator&amp;nbsp;type=&lt;span class=&quot;string&quot;&gt;&amp;quot;requiredstring&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;message&amp;nbsp;key=&lt;span class=&quot;string&quot;&gt;&amp;quot;errors.required&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/field-validator&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/field&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/validators&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;!DOCTYPE validators PUBLIC &amp;quot;-//OpenSymphony Group//XWork Validator 1.0.2//EN&amp;quot;
&amp;quot;http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd&amp;quot;&amp;gt;
&amp;lt;validators&amp;gt;
&amp;lt;field name=&amp;quot;person.firstName&amp;quot;&amp;gt;
&amp;lt;field-validator type=&amp;quot;requiredstring&amp;quot;&amp;gt;
&amp;lt;message key=&amp;quot;errors.required&amp;quot;/&amp;gt;
&amp;lt;/field-validator&amp;gt;
&amp;lt;/field&amp;gt;
&amp;lt;field name=&amp;quot;person.lastName&amp;quot;&amp;gt;
&amp;lt;field-validator type=&amp;quot;requiredstring&amp;quot;&amp;gt;
&amp;lt;message key=&amp;quot;errors.required&amp;quot;/&amp;gt;
&amp;lt;/field-validator&amp;gt;
&amp;lt;/field&amp;gt;
&amp;lt;/validators&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;The &amp;quot;errors.message&amp;quot; key in ApplicationResources*.properties (listed below) will use the field's &amp;quot;name&amp;quot; attribute to do internationalization. You can also give the &amp;lt;message&amp;gt; element a body if you don't need i18n.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; height=&quot;19&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;360&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;errors.required=${getText(fieldName)}&amp;nbsp;is&amp;nbsp;a&amp;nbsp;required&amp;nbsp;field.&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;errors.required=${getText(fieldName)} is a required field.&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Now you need to configure &lt;tt&gt;PersonAction&lt;/tt&gt; to know about &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://struts.apache.org/2.x/docs/using-visitor-field-validator.html&quot;&gt;visitor validation&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. To do this, create a &lt;tt&gt;PersonAction-validation.xml&lt;/tt&gt; file in &lt;em&gt;src/main/resources/**/webapp/action&lt;/em&gt; (you'll need to create this directory). Fill it with the following XML:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;!DOCTYPE&amp;nbsp;validators&amp;nbsp;PUBLIC&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;-//OpenSymphony&amp;nbsp;Group//XWork&amp;nbsp;Validator&amp;nbsp;1.0.2//EN&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;string&quot;&gt;&amp;quot;http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;validators&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;field&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;person&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;field-validator&amp;nbsp;type=&lt;span class=&quot;string&quot;&gt;&amp;quot;visitor&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;param&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;appendPrefix&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt;&lt;span&gt;&amp;lt;/param&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;message/&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/field-validator&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/field&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/validators&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;!DOCTYPE validators PUBLIC &amp;quot;-//OpenSymphony Group//XWork Validator 1.0.2//EN&amp;quot;
&amp;quot;http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd&amp;quot;&amp;gt;
&amp;lt;validators&amp;gt;
&amp;lt;field name=&amp;quot;person&amp;quot;&amp;gt;
&amp;lt;field-validator type=&amp;quot;visitor&amp;quot;&amp;gt;
&amp;lt;param name=&amp;quot;appendPrefix&amp;quot;&amp;gt;false&amp;lt;/param&amp;gt;
&amp;lt;message/&amp;gt;
&amp;lt;/field-validator&amp;gt;
&amp;lt;/field&amp;gt;
&amp;lt;/validators&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;table class=&quot;warningMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/forbidden.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;Unfortunately, Struts doesn't have a transparent mechanism for reading from the &lt;tt&gt;Person-validation.xml&lt;/tt&gt; file and marking fields as required on the UI. AppFuse's Spring MVC implementation use a LabelTag that makes this possible, but it also both use Commons Validator. It is my hope to someday provide this same functionality for Struts. In the meantime, the JSP tags &amp;quot;required&amp;quot; attribute has nothing to with the validation rules you specify. Rather, they simply add an asterisk to the label with no further functionality. &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Client-side validation&lt;/strong&gt;&lt;br /&gt;Client-side validation of model-based validation rules &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://jira.opensymphony.com/browse/XW-227&quot;&gt;doesn't work&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; with the Struts setup that AppFuse uses. Furthermore, I believe that Struts's client-side validation needs some additional features, namely: &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://jira.opensymphony.com/browse/WW-648&quot;&gt;allow cancelling&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; and &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://jira.opensymphony.com/browse/WW-647&quot;&gt;showing all errors in one dialog&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. Because of this, only server-side validation works in Struts+AppFuse. If you'd like, you can &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://raibledesigns.com/page/rd?anchor=webwork_s_validation_and_springobjectfactory&quot;&gt;read more&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; about my frustrations with client-side validation.
            &lt;p&gt;As a workaround, you can use per-action validation. Just copy the &lt;tt&gt;Person-validation.xml&lt;/tt&gt; file to the &amp;quot;webapp.action&amp;quot; package and rename it to &lt;tt&gt;PersonAction-validation.xml&lt;/tt&gt;. &lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Struts' validation interceptor is enabled by default, so you don't need to configure anything for validation to work.&lt;/p&gt;
&lt;p&gt;After saving all your files and running &lt;strong&gt;mvn jetty:run-war&lt;/strong&gt;, validation should kick in when you try to save this form. To test, go to &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://localhost:8080/editPerson.html?id=1&quot;&gt;http://localhost:8080/editPerson.html?id=1&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. If you erase the values in the firstName and lastName fields and click the Save button, you should see the following:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;&lt;img style=&quot;FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://www.appfuse.org/download/attachments/36/validationerror.png' _fcksavedurl='http://www.appfuse.org/download/attachments/36/validationerror.png',sizingMethod='scale'); WIDTH: 500px; HEIGHT: 350px&quot; height=&quot;350&quot; alt=&quot;&quot; src=&quot;http://www.appfuse.org/images/border/spacer.gif&quot; width=&quot;500&quot; border=&quot;1&quot; /&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;AppFuse is configured so that methods cancel, execute, delete, edit, list, and start are not validated. This allows you to go back from a form with errors on (like above) by pressing the Cancel button.&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;UsingStruts2-CreateaCanooWebTesttotestbrowserlikeactions&quot;&gt;&lt;/a&gt;Create a Canoo WebTest to test browser-like actions &lt;a name=&quot;UsingStruts2-webtest&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The next (optional) step in this tutorial is to create a &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://webtest.canoo.com/&quot;&gt;Canoo WebTest&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; to test the JSPs. This step is optional, because you can run the same tests manually through your browser. Regardless, it's a good idea to automate as much of your testing as possible. &lt;/p&gt;
&lt;p&gt;You can use the following URLs to test the different actions for adding, editing and saving a user.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Add - &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://localhost:8080/editPerson.html&quot;&gt;http://localhost:8080/editPerson.html&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. &lt;/li&gt;
    &lt;li&gt;Edit - &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://localhost:8080/editPerson.html?id=1&quot;&gt;http://localhost:8080/editPerson.html?id=1&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. &lt;/li&gt;
    &lt;li&gt;Delete - Use the edit link above and click on the Delete button. &lt;/li&gt;
    &lt;li&gt;Save - Click &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://localhost:8080/editPerson.html?id=1&quot;&gt;edit&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; and then click the Save button. &lt;/li&gt;
&lt;/ul&gt;
&lt;table class=&quot;infoMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/information.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;WebTest Recorder&lt;/strong&gt;&lt;br /&gt;There is a &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://webtestrecorder.canoo.com/&quot;&gt;WebTest Recorder&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; Firefox plugin that allows you to record your tests, rather than manually writing them.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Canoo tests are pretty slick in that they're simply configured in an XML file. To add tests for add, edit, save and delete, open &lt;em&gt;src/test/resources/web-tests.xml&lt;/em&gt; and add the following XML. You'll notice that this fragment has a target named ''PersonTests'' that runs all the related tests. &lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;!--&amp;nbsp;runs&amp;nbsp;person-related&amp;nbsp;tests&amp;nbsp;--&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;target&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;PersonTests&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;depends=&lt;span class=&quot;string&quot;&gt;&amp;quot;SearchPeople,EditPerson,SavePerson,AddPerson,DeletePerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;Call&amp;nbsp;and&amp;nbsp;executes&amp;nbsp;all&amp;nbsp;person&amp;nbsp;test&amp;nbsp;cases&amp;nbsp;(targets)&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;echo&amp;gt;Successfully&amp;nbsp;ran&amp;nbsp;all&amp;nbsp;Person&amp;nbsp;UI&amp;nbsp;tests!&amp;lt;/echo&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/target&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;!--&amp;nbsp;Verify&amp;nbsp;the&amp;nbsp;people&amp;nbsp;list&amp;nbsp;screen&amp;nbsp;displays&amp;nbsp;without&amp;nbsp;errors&amp;nbsp;--&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;target&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;SearchPeople&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;description=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Tests&amp;nbsp;search&amp;nbsp;for&amp;nbsp;and&amp;nbsp;displaying&amp;nbsp;all&amp;nbsp;people&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;webtest&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;searchPeople&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;config; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;steps&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;login; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;invoke&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;click&amp;nbsp;View&amp;nbsp;People&amp;nbsp;link&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;url=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/persons.html&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifytitle&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;we&amp;nbsp;should&amp;nbsp;see&amp;nbsp;the&amp;nbsp;personList&amp;nbsp;title&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text=&lt;span class=&quot;string&quot;&gt;&amp;quot;.*${personList.title}.*&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;regex=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/steps&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/webtest&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/target&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;!--&amp;nbsp;Verify&amp;nbsp;the&amp;nbsp;edit&amp;nbsp;person&amp;nbsp;screen&amp;nbsp;displays&amp;nbsp;without&amp;nbsp;errors&amp;nbsp;--&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;target&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;EditPerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;Tests&amp;nbsp;editing&amp;nbsp;an&amp;nbsp;existing&amp;nbsp;Person's&amp;nbsp;information&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;webtest&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;editPerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;config; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;steps&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;login; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;invoke&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;click&amp;nbsp;Edit&amp;nbsp;Person&amp;nbsp;link&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;url=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/editPerson.html?id=1&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifytitle&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;we&amp;nbsp;should&amp;nbsp;see&amp;nbsp;the&amp;nbsp;personDetail&amp;nbsp;title&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text=&lt;span class=&quot;string&quot;&gt;&amp;quot;.*${personDetail.title}.*&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;regex=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/steps&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/webtest&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/target&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;!--&amp;nbsp;Edit&amp;nbsp;a&amp;nbsp;person&amp;nbsp;and&amp;nbsp;then&amp;nbsp;save&amp;nbsp;--&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;target&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;SavePerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;Tests&amp;nbsp;editing&amp;nbsp;and&amp;nbsp;saving&amp;nbsp;a&amp;nbsp;user&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;webtest&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;savePerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;config; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;steps&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;login; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;invoke&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;click&amp;nbsp;Edit&amp;nbsp;Person&amp;nbsp;link&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;url=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/editPerson.html?id=1&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifytitle&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;we&amp;nbsp;should&amp;nbsp;see&amp;nbsp;the&amp;nbsp;personDetail&amp;nbsp;title&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text=&lt;span class=&quot;string&quot;&gt;&amp;quot;.*${personDetail.title}.*&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;regex=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;setinputfield&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;set&amp;nbsp;lastName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;name=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;person.lastName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;value=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Canoo&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;clickbutton&amp;nbsp;label=&lt;span class=&quot;string&quot;&gt;&amp;quot;${button.save}&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;description=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Click&amp;nbsp;Save&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifytitle&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;Page&amp;nbsp;re-appears&amp;nbsp;if&amp;nbsp;save&amp;nbsp;successful&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text=&lt;span class=&quot;string&quot;&gt;&amp;quot;.*${personDetail.title}.*&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;regex=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifytext&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;verify&amp;nbsp;success&amp;nbsp;message&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;text=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;${person.updated}&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/steps&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/webtest&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/target&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;!--&amp;nbsp;Add&amp;nbsp;a&amp;nbsp;new&amp;nbsp;Person&amp;nbsp;--&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;target&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;AddPerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;Adds&amp;nbsp;a&amp;nbsp;new&amp;nbsp;Person&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;webtest&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;addPerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;config; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;steps&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;login; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;invoke&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;click&amp;nbsp;Add&amp;nbsp;Button&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;url=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/editPerson.html&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifytitle&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;we&amp;nbsp;should&amp;nbsp;see&amp;nbsp;the&amp;nbsp;personDetail&amp;nbsp;title&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text=&lt;span class=&quot;string&quot;&gt;&amp;quot;.*${personDetail.title}.*&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;regex=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;setinputfield&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;set&amp;nbsp;firstName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;name=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;person.firstName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;value=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Abbie&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;setinputfield&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;set&amp;nbsp;lastName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;name=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;person.lastName&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;value=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Raible&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;clickbutton&amp;nbsp;label=&lt;span class=&quot;string&quot;&gt;&amp;quot;${button.save}&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;description=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Click&amp;nbsp;button&amp;nbsp;'Save'&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifytitle&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;Person&amp;nbsp;List&amp;nbsp;appears&amp;nbsp;if&amp;nbsp;save&amp;nbsp;successful&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text=&lt;span class=&quot;string&quot;&gt;&amp;quot;.*${personList.title}.*&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;regex=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifytext&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;verify&amp;nbsp;success&amp;nbsp;message&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;text=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;${person.added}&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/steps&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/webtest&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/target&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;!--&amp;nbsp;Delete&amp;nbsp;existing&amp;nbsp;person&amp;nbsp;--&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;target&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;DeletePerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;Deletes&amp;nbsp;existing&amp;nbsp;Person&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;webtest&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;deletePerson&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;config; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;steps&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;login; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;invoke&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;click&amp;nbsp;Edit&amp;nbsp;Person&amp;nbsp;link&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;url=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/editPerson.html?id=1&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;prepareDialogResponse&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;Confirm&amp;nbsp;delete&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;dialogType=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;confirm&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;response=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;clickbutton&amp;nbsp;label=&lt;span class=&quot;string&quot;&gt;&amp;quot;${button.delete}&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;description=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Click&amp;nbsp;button&amp;nbsp;'Delete'&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifyNoDialogResponses/&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifytitle&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;display&amp;nbsp;Person&amp;nbsp;List&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;text=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;.*${personList.title}.*&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;regex=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;verifytext&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;verify&amp;nbsp;success&amp;nbsp;message&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;text=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;${person.deleted}&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/steps&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/webtest&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/target&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;!-- runs person-related tests --&amp;gt;
&amp;lt;target name=&amp;quot;PersonTests&amp;quot;
depends=&amp;quot;SearchPeople,EditPerson,SavePerson,AddPerson,DeletePerson&amp;quot;
description=&amp;quot;Call and executes all person test cases (targets)&amp;quot;&amp;gt;
&amp;lt;echo&amp;gt;Successfully ran all Person UI tests!&amp;lt;/echo&amp;gt;
&amp;lt;/target&amp;gt;
&amp;lt;!-- Verify the people list screen displays without errors --&amp;gt;
&amp;lt;target name=&amp;quot;SearchPeople&amp;quot; description=&amp;quot;Tests search for and displaying all people&amp;quot;&amp;gt;
&amp;lt;webtest name=&amp;quot;searchPeople&amp;quot;&amp;gt;
&amp;amp;config;
&amp;lt;steps&amp;gt;
&amp;amp;login;
&amp;lt;invoke description=&amp;quot;click View People link&amp;quot; url=&amp;quot;/persons.html&amp;quot;/&amp;gt;
&amp;lt;verifytitle description=&amp;quot;we should see the personList title&amp;quot;
text=&amp;quot;.*${personList.title}.*&amp;quot; regex=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;/steps&amp;gt;
&amp;lt;/webtest&amp;gt;
&amp;lt;/target&amp;gt;
&amp;lt;!-- Verify the edit person screen displays without errors --&amp;gt;
&amp;lt;target name=&amp;quot;EditPerson&amp;quot;
description=&amp;quot;Tests editing an existing Person's information&amp;quot;&amp;gt;
&amp;lt;webtest name=&amp;quot;editPerson&amp;quot;&amp;gt;
&amp;amp;config;
&amp;lt;steps&amp;gt;
&amp;amp;login;
&amp;lt;invoke description=&amp;quot;click Edit Person link&amp;quot; url=&amp;quot;/editPerson.html?id=1&amp;quot;/&amp;gt;
&amp;lt;verifytitle description=&amp;quot;we should see the personDetail title&amp;quot;
text=&amp;quot;.*${personDetail.title}.*&amp;quot; regex=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;/steps&amp;gt;
&amp;lt;/webtest&amp;gt;
&amp;lt;/target&amp;gt;
&amp;lt;!-- Edit a person and then save --&amp;gt;
&amp;lt;target name=&amp;quot;SavePerson&amp;quot;
description=&amp;quot;Tests editing and saving a user&amp;quot;&amp;gt;
&amp;lt;webtest name=&amp;quot;savePerson&amp;quot;&amp;gt;
&amp;amp;config;
&amp;lt;steps&amp;gt;
&amp;amp;login;
&amp;lt;invoke description=&amp;quot;click Edit Person link&amp;quot; url=&amp;quot;/editPerson.html?id=1&amp;quot;/&amp;gt;
&amp;lt;verifytitle description=&amp;quot;we should see the personDetail title&amp;quot;
text=&amp;quot;.*${personDetail.title}.*&amp;quot; regex=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;setinputfield description=&amp;quot;set lastName&amp;quot; name=&amp;quot;person.lastName&amp;quot; value=&amp;quot;Canoo&amp;quot;/&amp;gt;
&amp;lt;clickbutton label=&amp;quot;${button.save}&amp;quot; description=&amp;quot;Click Save&amp;quot;/&amp;gt;
&amp;lt;verifytitle description=&amp;quot;Page re-appears if save successful&amp;quot;
text=&amp;quot;.*${personDetail.title}.*&amp;quot; regex=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;verifytext description=&amp;quot;verify success message&amp;quot; text=&amp;quot;${person.updated}&amp;quot;/&amp;gt;
&amp;lt;/steps&amp;gt;
&amp;lt;/webtest&amp;gt;
&amp;lt;/target&amp;gt;
&amp;lt;!-- Add a new Person --&amp;gt;
&amp;lt;target name=&amp;quot;AddPerson&amp;quot;
description=&amp;quot;Adds a new Person&amp;quot;&amp;gt;
&amp;lt;webtest name=&amp;quot;addPerson&amp;quot;&amp;gt;
&amp;amp;config;
&amp;lt;steps&amp;gt;
&amp;amp;login;
&amp;lt;invoke description=&amp;quot;click Add Button&amp;quot; url=&amp;quot;/editPerson.html&amp;quot;/&amp;gt;
&amp;lt;verifytitle description=&amp;quot;we should see the personDetail title&amp;quot;
text=&amp;quot;.*${personDetail.title}.*&amp;quot; regex=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;setinputfield description=&amp;quot;set firstName&amp;quot; name=&amp;quot;person.firstName&amp;quot; value=&amp;quot;Abbie&amp;quot;/&amp;gt;
&amp;lt;setinputfield description=&amp;quot;set lastName&amp;quot; name=&amp;quot;person.lastName&amp;quot; value=&amp;quot;Raible&amp;quot;/&amp;gt;
&amp;lt;clickbutton label=&amp;quot;${button.save}&amp;quot; description=&amp;quot;Click button 'Save'&amp;quot;/&amp;gt;
&amp;lt;verifytitle description=&amp;quot;Person List appears if save successful&amp;quot;
text=&amp;quot;.*${personList.title}.*&amp;quot; regex=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;verifytext description=&amp;quot;verify success message&amp;quot; text=&amp;quot;${person.added}&amp;quot;/&amp;gt;
&amp;lt;/steps&amp;gt;
&amp;lt;/webtest&amp;gt;
&amp;lt;/target&amp;gt;
&amp;lt;!-- Delete existing person --&amp;gt;
&amp;lt;target name=&amp;quot;DeletePerson&amp;quot;
description=&amp;quot;Deletes existing Person&amp;quot;&amp;gt;
&amp;lt;webtest name=&amp;quot;deletePerson&amp;quot;&amp;gt;
&amp;amp;config;
&amp;lt;steps&amp;gt;
&amp;amp;login;
&amp;lt;invoke description=&amp;quot;click Edit Person link&amp;quot; url=&amp;quot;/editPerson.html?id=1&amp;quot;/&amp;gt;
&amp;lt;prepareDialogResponse description=&amp;quot;Confirm delete&amp;quot; dialogType=&amp;quot;confirm&amp;quot; response=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;clickbutton label=&amp;quot;${button.delete}&amp;quot; description=&amp;quot;Click button 'Delete'&amp;quot;/&amp;gt;
&amp;lt;verifyNoDialogResponses/&amp;gt;
&amp;lt;verifytitle description=&amp;quot;display Person List&amp;quot; text=&amp;quot;.*${personList.title}.*&amp;quot; regex=&amp;quot;true&amp;quot;/&amp;gt;
&amp;lt;verifytext description=&amp;quot;verify success message&amp;quot; text=&amp;quot;${person.deleted}&amp;quot;/&amp;gt;
&amp;lt;/steps&amp;gt;
&amp;lt;/webtest&amp;gt;
&amp;lt;/target&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;After adding this, you should be able to run &lt;strong&gt;mvn integration-test -Dtest=PersonTests&lt;/strong&gt; and have these tests execute. If this command results in &amp;quot;BUILD SUCCESSFUL&amp;quot; - nice work!&lt;/p&gt;
&lt;p&gt;To include the PersonTests when all Canoo tests are run, add it as a dependency to the &amp;quot;run-all-tests&amp;quot; target in &lt;em&gt;src/test/resources/web-test.xml&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;target&amp;nbsp;name=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run-all-tests&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;depends=&lt;span class=&quot;string&quot;&gt;&amp;quot;Login,Logout,PasswordHint,Signup,UserTests,FlushCache,FileUpload,PersonTests&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;description=&lt;span class=&quot;string&quot;&gt;&amp;quot;Call&amp;nbsp;and&amp;nbsp;executes&amp;nbsp;all&amp;nbsp;test&amp;nbsp;cases&amp;nbsp;(targets)&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;target name=&amp;quot;run-all-tests&amp;quot;
depends=&amp;quot;Login,Logout,PasswordHint,Signup,UserTests,FlushCache,FileUpload,PersonTests&amp;quot;
description=&amp;quot;Call and executes all test cases (targets)&amp;quot;/&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;UsingStruts2-Addlinktomenu&quot;&gt;&lt;/a&gt;Add link to menu &lt;a name=&quot;UsingStruts2-menu&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The last step is to make the list, add, edit and delete functions visible to the user. The simplest way is to add a new link to the list of links in &lt;em&gt;src/main/webapp/WEB-INF/pages/mainMenu.jsp&lt;/em&gt;. Since this file doesn't exist in your project, you can copy it from target/projectname-version/WEB-INF/pages/mainMenu.jsp to your project with the following command:&lt;/p&gt;
&lt;div class=&quot;preformatted&quot;&gt;
&lt;div class=&quot;preformattedContent&quot;&gt;
&lt;pre&gt;cp target/projectname-version/WEB-INF/pages/mainMenu.jsp src/main/webapp/WEB-INF/pages
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then add the following link:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;li&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;a&amp;nbsp;href=&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;lt;c:url&amp;nbsp;value=&amp;quot;&lt;/span&gt;&lt;span&gt;/persons.html&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/&amp;gt;&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;lt;fmt:message&amp;nbsp;key=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;menu.viewPeople&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&amp;lt;/a&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/li&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;li&amp;gt;
&amp;lt;a href=&amp;quot;&amp;lt;c:url value=&amp;quot;/persons.html&amp;quot;/&amp;gt;&amp;quot;&amp;gt;&amp;lt;fmt:message key=&amp;quot;menu.viewPeople&amp;quot;/&amp;gt;&amp;lt;/a&amp;gt;
&amp;lt;/li&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Where &lt;tt&gt;menu.viewPeople&lt;/tt&gt; is an entry in &lt;em&gt;src/main/resources/ApplicationResources.properties&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;menu.viewPeople=View&amp;nbsp;People&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;menu.viewPeople=View People&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Modifying AppFuse core files&lt;/strong&gt;&lt;br /&gt;You can run also run &lt;strong&gt;war:inplace&lt;/strong&gt; to get the &lt;tt&gt;mainMenu.jsp&lt;/tt&gt; file in your project. You'll want to check your project into source control before you do this so you can delete files you don't modify.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The other (more likely) alternative is that you'll want to add it to the menu. To do this, add the following to &lt;em&gt;src/main/webapp/WEB-INF/menu-config.xml&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; height=&quot;19&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;489&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;Menu&amp;nbsp;name=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;PeopleMenu&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;title=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;menu.viewPeople&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;page=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/persons.html&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;Menu name=&amp;quot;PeopleMenu&amp;quot; title=&amp;quot;menu.viewPeople&amp;quot; page=&amp;quot;/persons.html&amp;quot;/&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Make sure the above XML is inside the &amp;lt;Menus&amp;gt; tag, but not within another &amp;lt;Menu&amp;gt;. Then create &lt;em&gt;src/main/webapp/common/menu.jsp&lt;/em&gt; and add the following code to it:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;%@&amp;nbsp;include&amp;nbsp;file=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/common/taglibs.jsp&amp;quot;&lt;/span&gt;&lt;span&gt;%&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;menu:useMenuDisplayer&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;Velocity&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;config=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;cssHorizontalMenu.vm&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;permissions=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;rolesAdapter&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;ul&amp;nbsp;id=&lt;span class=&quot;string&quot;&gt;&amp;quot;primary-nav&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;menuList&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;pad&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;amp;nbsp;&amp;lt;/li&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;c:&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;test=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;${empty&amp;nbsp;pageContext.request.remoteUser}&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;gt;&amp;lt;a&amp;nbsp;href=&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;lt;c:url&amp;nbsp;value=&amp;quot;&lt;/span&gt;&lt;span&gt;/login.jsp&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;/&amp;gt;&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;current&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;fmt:message&amp;nbsp;key=&lt;span class=&quot;string&quot;&gt;&amp;quot;login.title&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/c:&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;menu:displayMenu&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;MainMenu&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;menu:displayMenu&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;UserMenu&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;menu:displayMenu&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;PeopleMenu&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;menu:displayMenu&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;AdminMenu&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;menu:displayMenu&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;Logout&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/ul&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;lt;/menu:useMenuDisplayer&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;%@ include file=&amp;quot;/common/taglibs.jsp&amp;quot;%&amp;gt;
&amp;lt;menu:useMenuDisplayer name=&amp;quot;Velocity&amp;quot; config=&amp;quot;cssHorizontalMenu.vm&amp;quot; permissions=&amp;quot;rolesAdapter&amp;quot;&amp;gt;
&amp;lt;ul id=&amp;quot;primary-nav&amp;quot; class=&amp;quot;menuList&amp;quot;&amp;gt;
&amp;lt;li class=&amp;quot;pad&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/li&amp;gt;
&amp;lt;c:if test=&amp;quot;${empty pageContext.request.remoteUser}&amp;quot;&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;c:url value=&amp;quot;/login.jsp&amp;quot;/&amp;gt;&amp;quot; class=&amp;quot;current&amp;quot;&amp;gt;
&amp;lt;fmt:message key=&amp;quot;login.title&amp;quot;/&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/c:if&amp;gt;
&amp;lt;menu:displayMenu name=&amp;quot;MainMenu&amp;quot;/&amp;gt;
&amp;lt;menu:displayMenu name=&amp;quot;UserMenu&amp;quot;/&amp;gt;
&amp;lt;menu:displayMenu name=&amp;quot;PeopleMenu&amp;quot;/&amp;gt;
&amp;lt;menu:displayMenu name=&amp;quot;AdminMenu&amp;quot;/&amp;gt;
&amp;lt;menu:displayMenu name=&amp;quot;Logout&amp;quot;/&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;/menu:useMenuDisplayer&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Now if you run &lt;strong&gt;mvn jetty:run-war&lt;/strong&gt; and go to &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://localhost:8080/mainMenu.html&quot;&gt;http://localhost:8080/mainMenu.html&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;, you should see something like the screenshot below.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;&lt;img style=&quot;FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://www.appfuse.org/download/attachments/36/menu.png' _fcksavedurl='http://www.appfuse.org/download/attachments/36/menu.png',sizingMethod='scale'); WIDTH: 500px; HEIGHT: 282px&quot; height=&quot;282&quot; alt=&quot;&quot; src=&quot;http://www.appfuse.org/images/border/spacer.gif&quot; width=&quot;500&quot; border=&quot;1&quot; /&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Notice that there is a new link in your main screen (from mainMenu.jsp) and on the top in your menu bar (from menu.jsp).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That's it!&lt;/strong&gt;&lt;br /&gt;You've completed the full lifecycle of developing a set of master-detail pages with AppFuse and Struts 2 - &lt;strong&gt;Congratulations&lt;/strong&gt;! Now the real test is if you can run all the tests in your app without failure. To test, run &lt;strong&gt;mvn integration-test&lt;/strong&gt;. This will run all the unit and integration tests within your project.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Happy Day!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;span style=&quot;COLOR: green&quot;&gt;BUILD SUCCESSFUL&lt;br clear=&quot;all&quot; /&gt;Total time: 1 minute 30 seconds&lt;/span&gt;&amp;nbsp;&lt;!--
&lt;rdf:RDF xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;
xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot;
xmlns:trackback=&quot;http://madskills.com/public/xml/rss/module/trackback/&quot;&gt;
&lt;rdf:Description
rdf:about=&quot;http://appfuse.org/display/APF/Using+Struts+2&quot;
dc:identifier=&quot;http://appfuse.org/display/APF/Using+Struts+2&quot;
dc:title=&quot;Using Struts 2&quot;
trackback:ping=&quot;http://appfuse.org/rpc/trackback/36&quot; /&gt;
&lt;/rdf:RDF&gt;
--&gt;&amp;nbsp;
            &lt;div&gt;
                作者：xiong2009 发表于2007-8-23 19:07:00 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1756525&quot;&gt;原文链接&lt;/a&gt;
            &lt;/div&gt;
            &lt;div&gt;
            阅读：2192 评论：0 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1756525#comments&quot; target=&quot;_blank&quot;&gt;查看评论&lt;/a&gt;
            &lt;/div&gt;</description><pubDate>Thu, 23 Aug 2007 19:07:00 +0800</pubDate><author>xiong2009</author><guid isPermaLink="false">http://blog.csdn.net/xiong2009/article/details/1756525</guid><dc:creator>xiong2009</dc:creator><fs:srclink>http://blog.csdn.net/xiong2009/article/details/1756525</fs:srclink><fs:srcfeed>http://blog.csdn.net/xiong2009/Rss.aspx</fs:srcfeed><fs:itemid>feedsky/xiong2009/~1212304/602964771/1227063</fs:itemid></item><item><title>[原]appFuse2.x第五篇--Services</title><link>http://blog.csdn.net/xiong2009/article/details/1756523</link><description>&lt;p&gt;This tutorial will show you how to create a Business Facade class (and a JUnit Test) to talk to the DAO you created in the &lt;a title=&quot;Persistence&quot; href=&quot;http://www.appfuse.org/display/APF/Persistence&quot;&gt;Persistence Tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the context of AppFuse, this is called a Manager class. Its main responsibility is to act as a bridge between the persistence (DAO) layer and the web layer. It's also useful for de-coupling your presentation layer from your database layer (i.e. for Swing apps and web services). Managers should also be where you put any business logic for your application.&lt;/p&gt;
&lt;p&gt;You will learn two things:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;You don't need to write Managers if you just need generic CRUD functionality. &lt;/li&gt;
    &lt;li&gt;How to write Managers when you need custom functionality. &lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;&lt;a name=&quot;Services-TableofContents&quot;&gt;&lt;/a&gt;Table of Contents&lt;/h3&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;a title=&quot;personmanagerbean on Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services#Services-personmanagerbean&quot;&gt;Register a personManager bean definition&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;managerintf on Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services#Services-managerintf&quot;&gt;Create a Manager Interface&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;managertest on Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services#Services-managertest&quot;&gt;Create a Manager Test to test finder functionality&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;managerimpl on Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services#Services-managerimpl&quot;&gt;Create a Manager Implementation&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;runtest on Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services#Services-runtest&quot;&gt;Run the Manager Test&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;implreg on Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services#Services-implreg&quot;&gt;Register your Manager Implementation&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;emcktest on Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services#Services-emcktest&quot;&gt;Write the Manager Test using EasyMock&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;table class=&quot;infoMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/information.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Source Code&lt;/strong&gt;&lt;br /&gt;
            &lt;p&gt;The code for this tutorial is located in the &amp;quot;tutorial-service&amp;quot; module of the &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://code.google.com/p/appfuse-demos/&quot;&gt;appfuse-demos&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; project on Google Code. Use the following command to check it out from Subversion:&lt;/p&gt;
            &lt;div class=&quot;preformatted&quot;&gt;
            &lt;div class=&quot;preformattedContent&quot;&gt;
            &lt;pre&gt;svn checkout http://appfuse-demos.googlecode.com/svn/trunk/tutorial-service
&lt;/pre&gt;
            &lt;/div&gt;
            &lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;a name=&quot;Services-RegisterapersonManagerbeandefinition&quot;&gt;&lt;/a&gt;Register a personManager bean definition &lt;a name=&quot;Services-personmanagerbean&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;AppFuse 2.x doesn't require you to write a Manager or DAO to persist a POJO. You can use one of the pre-existing manager interfaces/implementations if all you need is CRUD on an object:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;GenericManager&lt;/strong&gt;: A generics-based class that requires you to create a Spring bean definition. &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;UniversalManager&lt;/strong&gt;: A class that requires you to cast to the specific object type. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;tt&gt;UniversalManagerImpl&lt;/tt&gt; class is already registered as a &amp;quot;manager&amp;quot; bean, so you can easily use it without any additional configuration. However, many developers prefer the generics-based Manager because it provides type safety. To register a personManager bean, its best to wrap the personDao bean.&lt;/p&gt;
&lt;table class=&quot;infoMacro&quot; cellspacing=&quot;5&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/information.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Transactions&lt;/strong&gt;&lt;br /&gt;All &lt;tt&gt;service.*Manager&lt;/tt&gt; beans will automatically be configured by Spring to wrap PROPOGATION_REQUIRED transactions around their method executions. This is done by the following Spring AOP configuration in appfuse-service.jar.
            &lt;div class=&quot;preformatted&quot;&gt;
            &lt;div class=&quot;preformattedContent&quot;&gt;
            &lt;pre&gt;&amp;lt;aop:config&amp;gt;     
    ...     
    &amp;lt;aop:advisor id=&amp;quot;managerTx&amp;quot; advice-ref=&amp;quot;txAdvice&amp;quot;          
        pointcut=&amp;quot;execution(* *..service.*Manager.*(..))&amp;quot; order=&amp;quot;2&amp;quot;/&amp;gt; 
&amp;lt;/aop:config&amp;gt;
&lt;/pre&gt;
            &lt;/div&gt;
            &lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Open your &lt;em&gt;src/main/webapp/WEB-INF/applicationContext.xml&lt;/em&gt; and replace the personDao bean with the following:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hibernate:&lt;/strong&gt;&lt;/p&gt;
&lt;style type=&quot;text/css&quot;&gt;

@import url( /download/resources/confluence.ext.code:code/shStyles.css );&lt;/style&gt;&lt;style type=&quot;text/css&quot;&gt;

.code TEXTAREA {
	PADDING-RIGHT: 0px! important; PADDING-LEFT: 0px! important; PADDING-BOTTOM: 0px! important; PADDING-TOP: 0px! important
}
.code INPUT {
	PADDING-RIGHT: 0px! important; PADDING-LEFT: 0px! important; PADDING-BOTTOM: 0px! important; PADDING-TOP: 0px! important
}&lt;/style&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shCore.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushCSharp.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushPhp.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushJScript.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushVb.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushSql.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushXml.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushShell.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushDelphi.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushPython.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushJava.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;bean&amp;nbsp;id=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;personManager&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.service.impl.GenericManagerImpl&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;constructor-arg&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;bean&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.dao.hibernate.GenericDaoHibernate&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;autowire=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;byType&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;constructor-arg&amp;nbsp;value=&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.tutorial.model.Person&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/bean&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/constructor-arg&amp;gt;&amp;nbsp; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/bean&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;bean id=&amp;quot;personManager&amp;quot; class=&amp;quot;org.appfuse.service.impl.GenericManagerImpl&amp;quot;&amp;gt;
&amp;lt;constructor-arg&amp;gt;
&amp;lt;bean class=&amp;quot;org.appfuse.dao.hibernate.GenericDaoHibernate&amp;quot; autowire=&amp;quot;byType&amp;quot;&amp;gt;
&amp;lt;constructor-arg value=&amp;quot;org.appfuse.tutorial.model.Person&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;
&amp;lt;/constructor-arg&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;iBATIS and JPA Configuration&lt;/strong&gt;&lt;br /&gt;For iBATIS and JPA, you'll need to change the nested DAO that gets injected into &lt;tt&gt;GenericManagerImpl&lt;/tt&gt;:
            &lt;ul&gt;
                &lt;li&gt;&lt;strong&gt;iBATIS:&lt;/strong&gt; &lt;tt&gt;&amp;lt;bean class=&amp;quot;org.appfuse.dao.ibatis.GenericDaoiBatis&amp;quot; ...&lt;/tt&gt; &lt;/li&gt;
                &lt;li&gt;&lt;strong&gt;JPA:&lt;/strong&gt; &lt;tt&gt;&amp;lt;bean class=&amp;quot;org.appfuse.dao.jpa.GenericDaoJpa&amp;quot; ...&lt;/tt&gt; &lt;/li&gt;
            &lt;/ul&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If you wrote the &lt;tt&gt;PersonDao&lt;/tt&gt; interface and implementation in the previous tutorial, you'll want to use the following for your personManager bean definition. If you don't, your &lt;tt&gt;PersonDaoTest&lt;/tt&gt; will fail because there's no longer an exposed personDao bean.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;bean&amp;nbsp;id=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;personManager&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.service.impl.GenericManagerImpl&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;constructor-arg&amp;nbsp;ref=&lt;span class=&quot;string&quot;&gt;&amp;quot;personDao&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/bean&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;bean id=&amp;quot;personManager&amp;quot; class=&amp;quot;org.appfuse.service.impl.GenericManagerImpl&amp;quot;&amp;gt;
&amp;lt;constructor-arg ref=&amp;quot;personDao&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Once you've created a personManager bean definition, you can use this bean on an object by adding the following setter method:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;setPersonManager(GenericManager&amp;lt;Person,&amp;nbsp;Long&amp;gt;&amp;nbsp;personManager)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.personManager&amp;nbsp;=&amp;nbsp;personManager;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;5&quot; readonly=&quot;readonly&quot; cols=&quot;65&quot; name=&quot;newcodemacro&quot;&gt;public void setPersonManager(GenericManager&amp;lt;Person, Long&amp;gt; personManager) {
this.personManager = personManager;
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;If you'd prefer to use the UniversalManager, you simply need to declare your set method as follows:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;setManager(UniversalManager&amp;nbsp;manager)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.manager&amp;nbsp;=&amp;nbsp;manager;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;public void setManager(UniversalManager manager) {
this.manager = manager;
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;No futher XML configuration is required when using this class.&lt;/p&gt;
&lt;table class=&quot;infoMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/information.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;The Spring Framework&lt;/strong&gt;&lt;br /&gt;To learn more about how Spring works, please see the &lt;a title=&quot;Spring&quot; href=&quot;http://www.appfuse.org/display/APF/Spring&quot;&gt;Spring Reference Guide&lt;/a&gt;.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;That's it! To persist an object with AppFuse 2.x, all you need to do is:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Create a POJO with annotations &lt;/li&gt;
    &lt;li&gt;Register it with your persistence framework &lt;/li&gt;
    &lt;li&gt;Write some XML to register a type-safe class to persist it, or write &lt;strong&gt;no&lt;/strong&gt; XML to use the Universal* classes. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Not only did you write data access code, you also used interfaces to abstract your implementation. This means that it should be possible to replace your persistence framework at any time.&lt;/p&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;
            &lt;p&gt;We hope to eliminate many of these steps in 2.2. For the final 2.0 release, you should be able to perform all 3 steps with the AppFuse Maven Plugin.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If you need more than just CRUD functionality, you'll want to continue reading below. If not, you can continue to &lt;a title=&quot;Web&quot; href=&quot;http://www.appfuse.org/display/APF/Web&quot;&gt;writing your web application&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;Services-CreateaManagerInterface&quot;&gt;&lt;/a&gt;Create a Manager Interface &lt;a name=&quot;Services-managerintf&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First off, create a &lt;tt&gt;PersonManager&lt;/tt&gt; interface (in the &lt;em&gt;src/main/java/**/service&lt;/em&gt; directory - you may need to create this first) and specify the finder method for any implementation classes. &lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.service; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.service.GenericManager; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.model.Person; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;java.util.List; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;interface&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonManager&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;GenericManager&amp;lt;Person,&amp;nbsp;Long&amp;gt;&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;List&amp;lt;Person&amp;gt;&amp;nbsp;findByLastName(String&amp;nbsp;lastName); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;package org.appfuse.tutorial.service;
import org.appfuse.service.GenericManager;
import org.appfuse.tutorial.model.Person;
import java.util.List;
public interface PersonManager extends GenericManager&amp;lt;Person, Long&amp;gt; {
public List&amp;lt;Person&amp;gt; findByLastName(String lastName);
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;Services-CreateaManagerTesttotestfinderfunctionality&quot;&gt;&lt;/a&gt;Create a Manager Test to test finder functionality &lt;a name=&quot;Services-managertest&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now you know what you want your manager to do, so it's time to write the tests. In this example, you will use mock objects to isolate your tests from external dependencies. This means you do not need a database set up to run these tests, and it will be easier to test different scenarios. In a large project, you could even test your Manager class before someone else finished writing the DAO implementation.&lt;/p&gt;
&lt;p&gt;You can write your own mock objects, but here you are going to use &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://jmock.org/&quot;&gt;jMock&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. Another widely use Mock Object library is &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.easymock.org/&quot;&gt;EasyMock&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Create &lt;tt&gt;PersonManagerImplTest&lt;/tt&gt; in &lt;em&gt;src/test/java/**/service/impl&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.service.impl; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;java.util.ArrayList; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;java.util.List; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.dao.PersonDao; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.model.Person; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.service.impl.BaseManagerMockTestCase; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.jmock.Mock; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonManagerImplTest&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BaseManagerMockTestCase&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonManagerImpl&amp;nbsp;manager&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;Mock&amp;nbsp;dao&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;Person&amp;nbsp;person&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;setUp()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Mock(PersonDao.&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;manager&amp;nbsp;=&amp;nbsp;new&amp;nbsp;PersonManagerImpl((PersonDao)&amp;nbsp;dao.proxy()); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;tearDown()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;manager&amp;nbsp;=&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testGetPerson()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;getPerson&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Long&amp;nbsp;id&amp;nbsp;=&amp;nbsp;7L; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;set&amp;nbsp;expected&amp;nbsp;behavior&amp;nbsp;on&amp;nbsp;dao &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.expects(once()).method(&lt;span class=&quot;string&quot;&gt;&amp;quot;get&amp;quot;&lt;/span&gt;&lt;span&gt;) &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.with(eq(id)) &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.will(returnValue(person)); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Person&amp;nbsp;result&amp;nbsp;=&amp;nbsp;manager.get(id); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertSame(person,&amp;nbsp;result); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.verify(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testGetPersons()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;getPersons&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;nbsp;people&amp;nbsp;=&amp;nbsp;new&amp;nbsp;ArrayList(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;set&amp;nbsp;expected&amp;nbsp;behavior&amp;nbsp;on&amp;nbsp;dao &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.expects(once()).method(&lt;span class=&quot;string&quot;&gt;&amp;quot;getAll&amp;quot;&lt;/span&gt;&lt;span&gt;) &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.will(returnValue(people)); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;nbsp;result&amp;nbsp;=&amp;nbsp;manager.getAll(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertSame(people,&amp;nbsp;result); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.verify(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testFindByLastName()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;findByLastName&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;nbsp;people&amp;nbsp;=&amp;nbsp;new&amp;nbsp;ArrayList(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;lastName&amp;nbsp;=&amp;nbsp;&lt;span class=&quot;string&quot;&gt;&amp;quot;Smith&amp;quot;&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;set&amp;nbsp;expected&amp;nbsp;behavior&amp;nbsp;on&amp;nbsp;dao &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.expects(once()).method(&lt;span class=&quot;string&quot;&gt;&amp;quot;findByLastName&amp;quot;&lt;/span&gt;&lt;span&gt;) &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.with(eq(lastName)) &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.will(returnValue(people)); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;nbsp;result&amp;nbsp;=&amp;nbsp;manager.findByLastName(lastName); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertSame(people,&amp;nbsp;result); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.verify(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testSavePerson()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;savePerson&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;set&amp;nbsp;expected&amp;nbsp;behavior&amp;nbsp;on&amp;nbsp;dao &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.expects(once()).method(&lt;span class=&quot;string&quot;&gt;&amp;quot;save&amp;quot;&lt;/span&gt;&lt;span&gt;) &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.with(same(person)) &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.will(returnValue(person)); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;manager.save(person); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.verify(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testRemovePerson()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;removePerson&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Long&amp;nbsp;id&amp;nbsp;=&amp;nbsp;11L; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;set&amp;nbsp;expected&amp;nbsp;behavior&amp;nbsp;on&amp;nbsp;dao &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.expects(once()).method(&lt;span class=&quot;string&quot;&gt;&amp;quot;remove&amp;quot;&lt;/span&gt;&lt;span&gt;) &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.with(eq(id)) &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.isVoid(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;manager.remove(id); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.verify(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;package org.appfuse.tutorial.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.appfuse.tutorial.dao.PersonDao;
import org.appfuse.tutorial.model.Person;
import org.appfuse.service.impl.BaseManagerMockTestCase;
import org.jmock.Mock;
public class PersonManagerImplTest extends BaseManagerMockTestCase {
private PersonManagerImpl manager = null;
private Mock dao = null;
private Person person = null;
protected void setUp() throws Exception {
dao = new Mock(PersonDao.class);
manager = new PersonManagerImpl((PersonDao) dao.proxy());
}
protected void tearDown() throws Exception {
manager = null;
}
public void testGetPerson() {
log.debug(&amp;quot;testing getPerson&amp;quot;);
Long id = 7L;
person = new Person();
// set expected behavior on dao
dao.expects(once()).method(&amp;quot;get&amp;quot;)
.with(eq(id))
.will(returnValue(person));
Person result = manager.get(id);
assertSame(person, result);
dao.verify();
}
public void testGetPersons() {
log.debug(&amp;quot;testing getPersons&amp;quot;);
List people = new ArrayList();
// set expected behavior on dao
dao.expects(once()).method(&amp;quot;getAll&amp;quot;)
.will(returnValue(people));
List result = manager.getAll();
assertSame(people, result);
dao.verify();
}
public void testFindByLastName() {
log.debug(&amp;quot;testing findByLastName&amp;quot;);
List people = new ArrayList();
String lastName = &amp;quot;Smith&amp;quot;;
// set expected behavior on dao
dao.expects(once()).method(&amp;quot;findByLastName&amp;quot;)
.with(eq(lastName))
.will(returnValue(people));
List result = manager.findByLastName(lastName);
assertSame(people, result);
dao.verify();
}
public void testSavePerson() {
log.debug(&amp;quot;testing savePerson&amp;quot;);
person = new Person();
// set expected behavior on dao
dao.expects(once()).method(&amp;quot;save&amp;quot;)
.with(same(person))
.will(returnValue(person));
manager.save(person);
dao.verify();
}
public void testRemovePerson() {
log.debug(&amp;quot;testing removePerson&amp;quot;);
Long id = 11L;
person = new Person();
// set expected behavior on dao
dao.expects(once()).method(&amp;quot;remove&amp;quot;)
.with(eq(id))
.isVoid();
manager.remove(id);
dao.verify();
}
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;This will not compile, as you have not created the &lt;tt&gt;PersonManagerImpl&lt;/tt&gt; class it tests. &lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;Services-CreateaManagerImplementation&quot;&gt;&lt;/a&gt;Create a Manager Implementation &lt;a name=&quot;Services-managerimpl&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The next step is to create a &lt;tt&gt;PersonManagerImpl&lt;/tt&gt; class that implements the methods in PersonManager.&lt;/p&gt;
&lt;p&gt;Create PersonManagerImpl.java in &lt;em&gt;src/main/java/**/service/impl&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.service.impl; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.dao.PersonDao; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.model.Person; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.service.PersonManager; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.service.impl.GenericManagerImpl; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;java.util.List; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonManagerImpl&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;GenericManagerImpl&amp;lt;Person,&amp;nbsp;Long&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;implements&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonManager&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PersonDao&amp;nbsp;personDao; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonManagerImpl(PersonDao&amp;nbsp;personDao)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;super(personDao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.personDao&amp;nbsp;=&amp;nbsp;personDao; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;List&amp;lt;Person&amp;gt;&amp;nbsp;findByLastName(String&amp;nbsp;lastName)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;personDao.findByLastName(lastName); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;package org.appfuse.tutorial.service.impl;
import org.appfuse.tutorial.dao.PersonDao;
import org.appfuse.tutorial.model.Person;
import org.appfuse.tutorial.service.PersonManager;
import org.appfuse.service.impl.GenericManagerImpl;
import java.util.List;
public class PersonManagerImpl extends GenericManagerImpl&amp;lt;Person, Long&amp;gt; implements PersonManager {
PersonDao personDao;
public PersonManagerImpl(PersonDao personDao) {
super(personDao);
this.personDao = personDao;
}
public List&amp;lt;Person&amp;gt; findByLastName(String lastName) {
return personDao.findByLastName(lastName);
}
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Now before you run your tests, review your test class to make sure that it will test all possible conditions.&lt;/p&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;I would put any complicated code in protected methods and go back and add extra test cases at this stage. &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;a name=&quot;Services-RuntheManagerTest&quot;&gt;&lt;/a&gt;Run the Manager Test &lt;a name=&quot;Services-runtest&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Save all your edited files and try running &lt;strong&gt;mvn test -Dtest=PersonManagerImplTest&lt;/strong&gt;. &lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;Services-RegisteryourManagerImplementation&quot;&gt;&lt;/a&gt;Register your Manager Implementation &lt;a name=&quot;Services-implreg&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Open your &lt;em&gt;src/main/webapp/WEB-INF/applicationContext.xml&lt;/em&gt; file and replace the personDao bean with the following:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;bean&amp;nbsp;id=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;personManager&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.tutorial.service.impl.PersonManagerImpl&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;constructor-arg&amp;nbsp;ref=&lt;span class=&quot;string&quot;&gt;&amp;quot;personDao&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/bean&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;bean id=&amp;quot;personManager&amp;quot; class=&amp;quot;org.appfuse.tutorial.service.impl.PersonManagerImpl&amp;quot;&amp;gt;
&amp;lt;constructor-arg ref=&amp;quot;personDao&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;
            &lt;p&gt;The Web application tutorials assume that you will be using the GenericManager. If you follow them after making this change, you will need to change all the references in their code from the GenericManager to your new PersonManager interface. For example:&lt;/p&gt;
            &lt;div class=&quot;preformatted&quot;&gt;
            &lt;div class=&quot;preformattedContent&quot;&gt;
            &lt;pre&gt;private PersonManager personManager;

public void setPersonManager(PersonManager personManager) {
    this.personManager = personManager;
}
&lt;/pre&gt;
            &lt;/div&gt;
            &lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;That's it. If you want to see how to use EasyMock instead of JMock, then carry on reading. If not, you can continue to &lt;a title=&quot;Web&quot; href=&quot;http://www.appfuse.org/display/APF/Web&quot;&gt;writing your web application&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;Services-UsingEasyMockinsteadofJUnitinUnitTests&quot;&gt;&lt;/a&gt;Using EasyMock instead of JUnit in Unit Tests &lt;a name=&quot;Services-emcktest&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sooner or later, you will want to add extra dependencies into your project.&lt;/p&gt;
&lt;p&gt;AppFuse currently ships with JMock, but not &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.easymock.org/&quot;&gt;EasyMock&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;, so this section will show you how to add EasyMock as a project dependency.&lt;/p&gt;
&lt;p&gt;Edit your &lt;em&gt;pom.xml&lt;/em&gt; file in your project's top level directory. Add EasyMock as a dependency in the &amp;lt;dependencies&amp;gt; element:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;dependencies&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;... &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;dependency&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;groupId&amp;gt;org.easymock&amp;lt;/groupId&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;artifactId&amp;gt;easymock&amp;lt;/artifactId&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;version&amp;gt;2.2&amp;lt;/version&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/dependency&amp;gt; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;lt;/dependencies&amp;gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;dependencies&amp;gt;
...
&amp;lt;dependency&amp;gt;
&amp;lt;groupId&amp;gt;org.easymock&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;easymock&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;2.2&amp;lt;/version&amp;gt;
&amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;EasyMock is only required during testing, and you don't want it packaged in your application, so it's restricted it to a scope of &lt;em&gt;test&lt;/em&gt;.&lt;/p&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;
            &lt;p&gt;To remove jMock and add EasyMock to references regenerate project with &lt;strong&gt;mvn install eclipse:eclipse&lt;/strong&gt; for Eclipse or &lt;strong&gt;mvn idea:idea&lt;/strong&gt; for IDEA.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Edit the &lt;tt&gt;PersonManagerImplTest&lt;/tt&gt; class you wrote above so it looks as follows:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.service.impl; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;java.util.ArrayList; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;java.util.List; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.dao.PersonDao; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.model.Person; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.easymock.EasyMock.*; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.apache.commons.logging.LogFactory; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.apache.commons.logging.Log; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;junit.framework.TestCase; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonManagerImplTest&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;TestCase&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;Log&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;&amp;nbsp;=&amp;nbsp;LogFactory.getLog(PersonManagerImplTest.&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonManagerImpl&amp;nbsp;manager&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonDao&amp;nbsp;dao&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;Person&amp;nbsp;person&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;setUp()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;setUpDao&amp;nbsp;for&amp;nbsp;PersonManagerImplTest&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao&amp;nbsp;=&amp;nbsp;createStrictMock(PersonDao.&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;manager&amp;nbsp;=&amp;nbsp;new&amp;nbsp;PersonManagerImpl((PersonDao)&amp;nbsp;dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testGetPerson()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;getPerson&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Long&amp;nbsp;id&amp;nbsp;=&amp;nbsp;7L; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;set&amp;nbsp;expected&amp;nbsp;behavior&amp;nbsp;on&amp;nbsp;dao &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expect(dao.get(id)).andReturn(person); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;replay(dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Person&amp;nbsp;result&amp;nbsp;=&amp;nbsp;manager.get(id); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertSame(person,&amp;nbsp;result); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verify(dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testGetPersons()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;getPersons&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;nbsp;people&amp;nbsp;=&amp;nbsp;new&amp;nbsp;ArrayList(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;set&amp;nbsp;expected&amp;nbsp;behavior&amp;nbsp;on&amp;nbsp;dao &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expect(dao.getAll()).andReturn(people); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;replay(dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;nbsp;result&amp;nbsp;=&amp;nbsp;manager.getAll(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertSame(people,&amp;nbsp;result); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verify(dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testGetByLastName()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;getByLastName&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;nbsp;people&amp;nbsp;=&amp;nbsp;new&amp;nbsp;ArrayList(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;lastName&amp;nbsp;=&amp;nbsp;&lt;span class=&quot;string&quot;&gt;&amp;quot;Smith&amp;quot;&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;set&amp;nbsp;expected&amp;nbsp;behavior&amp;nbsp;on&amp;nbsp;dao &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expect(dao.findByLastName(lastName)).andReturn(people); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;replay(dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;nbsp;result&amp;nbsp;=&amp;nbsp;manager.findByLastName(lastName); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertSame(people,&amp;nbsp;result); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verify(dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testSavePerson()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;savePerson&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;set&amp;nbsp;expected&amp;nbsp;behavior&amp;nbsp;on&amp;nbsp;dao &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expect(dao.save(person)).andReturn(person); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;replay(dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;manager.save(person); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verify(dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testRemovePerson()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;testing&amp;nbsp;removePerson&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Long&amp;nbsp;id&amp;nbsp;=&amp;nbsp;11L; &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;//&amp;nbsp;set&amp;nbsp;expected&amp;nbsp;behavior&amp;nbsp;on&amp;nbsp;dao &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dao.remove(id); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;replay(dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;manager.remove(id); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verify(dao); &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;package org.appfuse.tutorial.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.appfuse.tutorial.dao.PersonDao;
import org.appfuse.tutorial.model.Person;
import static org.easymock.EasyMock.*;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import junit.framework.TestCase;
public class PersonManagerImplTest extends TestCase {
private final Log log = LogFactory.getLog(PersonManagerImplTest.class);
private PersonManagerImpl manager = null;
private PersonDao dao = null;
private Person person = null;
protected void setUp() throws Exception {
log.debug(&amp;quot;setUpDao for PersonManagerImplTest&amp;quot;);
dao = createStrictMock(PersonDao.class);
manager = new PersonManagerImpl((PersonDao) dao);
}
public void testGetPerson() {
log.debug(&amp;quot;testing getPerson&amp;quot;);
Long id = 7L;
person = new Person();
// set expected behavior on dao
expect(dao.get(id)).andReturn(person);
replay(dao);
Person result = manager.get(id);
assertSame(person, result);
verify(dao);
}
public void testGetPersons() {
log.debug(&amp;quot;testing getPersons&amp;quot;);
List people = new ArrayList();
// set expected behavior on dao
expect(dao.getAll()).andReturn(people);
replay(dao);
List result = manager.getAll();
assertSame(people, result);
verify(dao);
}
public void testGetByLastName() {
log.debug(&amp;quot;testing getByLastName&amp;quot;);
List people = new ArrayList();
String lastName = &amp;quot;Smith&amp;quot;;
// set expected behavior on dao
expect(dao.findByLastName(lastName)).andReturn(people);
replay(dao);
List result = manager.findByLastName(lastName);
assertSame(people, result);
verify(dao);
}
public void testSavePerson() {
log.debug(&amp;quot;testing savePerson&amp;quot;);
person = new Person();
// set expected behavior on dao
expect(dao.save(person)).andReturn(person);
replay(dao);
manager.save(person);
verify(dao);
}
public void testRemovePerson() {
log.debug(&amp;quot;testing removePerson&amp;quot;);
Long id = 11L;
person = new Person();
// set expected behavior on dao
dao.remove(id);
replay(dao);
manager.remove(id);
verify(dao);
}
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Note that this class extends junit.framework.TestCase and not an EasyMock class. This makes EasyMock a good choice for annotation based test frameworks such as &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://junit.org/&quot;&gt;JUnit 4&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; and &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://testng.org/doc/&quot;&gt;TestNG&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. Unfortunately (at the time of writing) Maven does not work properly with these frameworks.&lt;/p&gt;
&lt;p&gt;Now check everything works by running &lt;strong&gt;mvn test -Dtest=PersonManagerImplTest&lt;/strong&gt; again. &lt;/p&gt;
&lt;p&gt;That's it, you can continue to &lt;a title=&quot;Web&quot; href=&quot;http://www.appfuse.org/display/APF/Web&quot;&gt;writing your web application&lt;/a&gt;.&lt;/p&gt;
&lt;!--
&lt;rdf:RDF xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;
xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot;
xmlns:trackback=&quot;http://madskills.com/public/xml/rss/module/trackback/&quot;&gt;
&lt;rdf:Description
rdf:about=&quot;http://appfuse.org/display/APF/Services&quot;
dc:identifier=&quot;http://appfuse.org/display/APF/Services&quot;
dc:title=&quot;Services&quot;
trackback:ping=&quot;http://appfuse.org/rpc/trackback/31&quot; /&gt;
&lt;/rdf:RDF&gt;
--&gt;&amp;nbsp;
            &lt;div&gt;
                作者：xiong2009 发表于2007-8-23 19:06:00 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1756523&quot;&gt;原文链接&lt;/a&gt;
            &lt;/div&gt;
            &lt;div&gt;
            阅读：1020 评论：0 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1756523#comments&quot; target=&quot;_blank&quot;&gt;查看评论&lt;/a&gt;
            &lt;/div&gt;</description><pubDate>Thu, 23 Aug 2007 19:06:00 +0800</pubDate><author>xiong2009</author><guid isPermaLink="false">http://blog.csdn.net/xiong2009/article/details/1756523</guid><dc:creator>xiong2009</dc:creator><fs:srclink>http://blog.csdn.net/xiong2009/article/details/1756523</fs:srclink><fs:srcfeed>http://blog.csdn.net/xiong2009/Rss.aspx</fs:srcfeed><fs:itemid>feedsky/xiong2009/~1212304/602964772/1227063</fs:itemid></item><item><title>[原]appFuse2.x第四篇--Using Hibernate</title><link>http://blog.csdn.net/xiong2009/article/details/1756515</link><description>&lt;p&gt;This tutorial will show you two things: &lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;You don't need to write DAOs if you just need generic CRUD functionality. &lt;/li&gt;
    &lt;li&gt;How to write DAOs when you need custom functionality. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you're new to Hibernate, you might want to read the &lt;a title=&quot;Hibernate&quot; href=&quot;http://www.appfuse.org/display/APF/Hibernate&quot;&gt;Hibernate Reference Guide&lt;/a&gt; before starting this tutorial.&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;UsingHibernate-TableofContents&quot;&gt;&lt;/a&gt;Table of Contents&lt;/h3&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;a title=&quot;persondaobean on Using Hibernate&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Hibernate#UsingHibernate-persondaobean&quot;&gt;Register a personDao bean definition&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;daotest on Using Hibernate&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Hibernate#UsingHibernate-daotest&quot;&gt;Create a DAO Test to test finder functionality&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;daoimpl on Using Hibernate&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Hibernate#UsingHibernate-daoimpl&quot;&gt;Create a DAO Interface and implementation&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;runtest on Using Hibernate&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Hibernate#UsingHibernate-runtest&quot;&gt;Run the DAO Test&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;table class=&quot;infoMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/information.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Source Code&lt;/strong&gt;&lt;br /&gt;
            &lt;p&gt;The code for this tutorial is located in the &amp;quot;tutorial-hibernate&amp;quot; module of the &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://code.google.com/p/appfuse-demos/&quot;&gt;appfuse-demos&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; project on Google Code. Use the following command to check it out from Subversion:&lt;/p&gt;
            &lt;div class=&quot;preformatted&quot;&gt;
            &lt;div class=&quot;preformattedContent&quot;&gt;
            &lt;pre&gt;svn checkout http://appfuse-demos.googlecode.com/svn/trunk/tutorial-hibernate
&lt;/pre&gt;
            &lt;/div&gt;
            &lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;UsingHibernate-RegisterapersonDaobeandefinition&quot;&gt;&lt;/a&gt;Register a personDao bean definition &lt;a name=&quot;UsingHibernate-persondaobean&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;AppFuse 2.x doesn't require you to write a DAO to persist a POJO. You can use one of the pre-existing classes if all you need is CRUD on an object:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;GenericDaoHibernate&lt;/strong&gt;: A generics-based class that requires you to create a Spring bean definition. &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;UniversalDaoHibernate&lt;/strong&gt;: A class that requires you to cast to the specific object type. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;tt&gt;UniversalDaoHibernate&lt;/tt&gt; class is already registered as a &amp;quot;dao&amp;quot; bean, so you can easily use it without any additional configuration. However, many developers prefer the generics-based DAO because it provides type safety. To register a personDao bean, create &lt;em&gt;src/main/webapp/WEB-INF/applicationContext.xml&lt;/em&gt; (or &lt;em&gt;core/src/main/resources/applicationContext.xml&lt;/em&gt; for a modular archetype) and add the following to it:&lt;/p&gt;
&lt;p&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;The &lt;em&gt;applicationContext.xml&lt;/em&gt; file should already exist if you're using AppFuse 2.0 M5+.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;style type=&quot;text/css&quot;&gt;



@import url( /download/resources/confluence.ext.code:code/shStyles.css );&lt;/style&gt;&lt;style type=&quot;text/css&quot;&gt;



.code TEXTAREA {
	PADDING-RIGHT: 0px! important; PADDING-LEFT: 0px! important; PADDING-BOTTOM: 0px! important; PADDING-TOP: 0px! important
}
.code INPUT {
	PADDING-RIGHT: 0px! important; PADDING-LEFT: 0px! important; PADDING-BOTTOM: 0px! important; PADDING-TOP: 0px! important
}&lt;/style&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shCore.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushCSharp.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushPhp.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushJScript.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushVb.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushSql.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushXml.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushShell.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushDelphi.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushPython.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushJava.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span&gt;&amp;lt;?xml&amp;nbsp;version=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;encoding=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span&gt;?&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;lt;beans&amp;nbsp;xmlns=&lt;span class=&quot;string&quot;&gt;&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:xsi=&lt;span class=&quot;string&quot;&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xsi:schemaLocation=&amp;quot;http:&lt;span class=&quot;comment&quot;&gt;//www.springframework.org/schema/beans &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;http:&lt;span class=&quot;comment&quot;&gt;//www.springframework.org/schema/beans/spring-beans-2.0.xsd&amp;quot;&amp;gt; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;bean&amp;nbsp;id=&lt;span class=&quot;string&quot;&gt;&amp;quot;personDao&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.dao.hibernate.GenericDaoHibernate&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;constructor-arg&amp;nbsp;value=&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.tutorial.model.Person&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;sessionFactory&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;ref=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;sessionFactory&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/bean&amp;gt;&amp;nbsp; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;
xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd&amp;quot;&amp;gt;
&amp;lt;bean id=&amp;quot;personDao&amp;quot; class=&amp;quot;org.appfuse.dao.hibernate.GenericDaoHibernate&amp;quot;&amp;gt;
&amp;lt;constructor-arg value=&amp;quot;org.appfuse.tutorial.model.Person&amp;quot;/&amp;gt;
&amp;lt;property name=&amp;quot;sessionFactory&amp;quot; ref=&amp;quot;sessionFactory&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;
&amp;lt;/beans&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;After doing this, you can use this bean on an object by adding the following setter method:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table height=&quot;53&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;448&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;setPersonDao(GenericDao&amp;lt;Person,&amp;nbsp;Long&amp;gt;&amp;nbsp;personDao)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.personDao&amp;nbsp;=&amp;nbsp;personDao; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;}&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;public void setPersonDao(GenericDao&amp;lt;Person, Long&amp;gt; personDao) {
this.personDao = personDao;
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;If you need more than just CRUD functionality, you'll want to continue reading below. If not, you can continue to &lt;a title=&quot;Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services&quot;&gt;Creating new Managers&lt;/a&gt;. This is a tutorial for creating Business Facades, which are similar to &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://java.sun.com/blueprints/patterns/SessionFacade.html&quot;&gt;Session Facades&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;, but don't use EJBs. These facades are used to provide communication from the front-end to the DAO layer.&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;UsingHibernate-CreateaDAOTesttotestfinderfunctionality&quot;&gt;&lt;/a&gt;Create a DAO Test to test finder functionality &lt;a name=&quot;UsingHibernate-daotest&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now you'll create a DaoTest to test that your DAO works. &amp;quot;Wait a minute,&amp;quot; you say, &amp;quot;I haven't created a DAO!&amp;quot; You are correct. However, I've found that &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.artima.com/intv/testdriven.html&quot;&gt;Test-Driven Development&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; breeds higher quality software. For years, I thought &lt;strong&gt;write your test before your class&lt;/strong&gt; was hogwash. It just seemed stupid. Then I tried it and I found that it works great. The only reason I do test-driven stuff now is because I've found it rapidly speeds up the process of software development.&lt;/p&gt;
&lt;p&gt;To start, create a &lt;tt&gt;PersonDaoTest.java&lt;/tt&gt; class in your &lt;em&gt;src/test/java/**/dao&lt;/em&gt; directory (or &lt;em&gt;core/src/test/java/**/dao&lt;/em&gt; directory for a modular archetype). This class should extend &lt;tt&gt;org.appfuse.dao.BaseDaoTestCase&lt;/tt&gt;, a subclass of Spring's &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.springframework.org/docs/api/org/springframework/test/AbstractTransactionalDataSourceSpringContextTests.html&quot;&gt;AbstractTransactionalDataSourceSpringContextTests&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. This parent class is used to load Spring's ApplicationContext (since Spring binds interfaces to implementations), and for (optionally) loading a .properties file that has the same name as your &lt;tt&gt;*Test.class&lt;/tt&gt;. In this example, if you put a &lt;tt&gt;PersonDaoTest.properties&lt;/tt&gt; file in &lt;em&gt;src/test/resources/org/appfuse/tutorial/dao&lt;/em&gt;, this file's properties will be available via an &amp;quot;rb&amp;quot; variable. &lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.dao; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;java.util.List; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.dao.BaseDaoTestCase; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.model.Person; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.springframework.dao.DataAccessException; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonDaoTest&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BaseDaoTestCase&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonDao&amp;nbsp;personDao&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;setPersonDao(PersonDao&amp;nbsp;personDao)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.personDao&amp;nbsp;=&amp;nbsp;personDao; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;}&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;package org.appfuse.tutorial.dao;
import java.util.List;
import org.appfuse.dao.BaseDaoTestCase;
import org.appfuse.tutorial.model.Person;
import org.springframework.dao.DataAccessException;
public class PersonDaoTest extends BaseDaoTestCase {
private PersonDao personDao = null;
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;The code you see above is what you need for a basic Spring integration test that initializes and configures an implementation of PersonDao. Spring will use autowiring by name to call the &lt;tt&gt;setPersonDao()&lt;/tt&gt; method and set the &amp;quot;personDao&amp;quot; bean as a dependency of this class.&lt;/p&gt;
&lt;p&gt;Now you need test that the finder method works in your DAO. To do this, create a method that begin with &amp;quot;test&amp;quot; (all lower case). As long as this method is public, has a &lt;tt&gt;void&lt;/tt&gt; return type and take no arguments, it invoked and run by JUnit. Add the following method to your &lt;tt&gt;PersonDaoTest.java&lt;/tt&gt; file:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testFindPersonByLastName()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;lt;Person&amp;gt;&amp;nbsp;people&amp;nbsp;=&amp;nbsp;personDao.findByLastName(&lt;span class=&quot;string&quot;&gt;&amp;quot;Raible&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertTrue(people.size()&amp;nbsp;&amp;gt;&amp;nbsp;0); &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;}&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;public void testFindPersonByLastName() throws Exception {
List&amp;lt;Person&amp;gt; people = personDao.findByLastName(&amp;quot;Raible&amp;quot;);
assertTrue(people.size() &amp;gt; 0);
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;You'll notice that this method relies on pre-existing data in order to pass. The &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://mojo.codehaus.org/dbunit-maven-plugin/&quot;&gt;DbUnit Maven Plugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; is used to populate the database with test data before the tests are run, so you can simply add the new table/record to the &lt;em&gt;src/test/resources/sample-data.xml&lt;/em&gt; file (or &lt;em&gt;core/src/test/resources/sample-data.xml&lt;/em&gt; for a modular archetype).&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span&gt;&amp;lt;table&amp;nbsp;name=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;'person'&lt;/span&gt;&lt;span&gt;&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;column&amp;gt;id&amp;lt;/column&amp;gt; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;column&amp;gt;first_name&amp;lt;/column&amp;gt; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;column&amp;gt;last_name&amp;lt;/column&amp;gt; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;row&amp;gt; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;1&amp;lt;/value&amp;gt; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;Matt&amp;lt;/value&amp;gt; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;Raible&amp;lt;/value&amp;gt; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/row&amp;gt; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;lt;/table&amp;gt;&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;table name='person'&amp;gt;
&amp;lt;column&amp;gt;id&amp;lt;/column&amp;gt;
&amp;lt;column&amp;gt;first_name&amp;lt;/column&amp;gt;
&amp;lt;column&amp;gt;last_name&amp;lt;/column&amp;gt;
&amp;lt;row&amp;gt;
&amp;lt;value&amp;gt;1&amp;lt;/value&amp;gt;
&amp;lt;value&amp;gt;Matt&amp;lt;/value&amp;gt;
&amp;lt;value&amp;gt;Raible&amp;lt;/value&amp;gt;
&amp;lt;/row&amp;gt;
&amp;lt;/table&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Since the PersonDao you're about to write includes CRUD functionality, you can also write a test to verify CRUD works properly.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.springframework.dao.DataAccessException; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;testAddAndRemovePerson()&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;throws&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Person&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.setFirstName(&lt;span class=&quot;string&quot;&gt;&amp;quot;Country&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.setLastName(&lt;span class=&quot;string&quot;&gt;&amp;quot;Bry&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;personDao.save(person); &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;flush(); &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person&amp;nbsp;=&amp;nbsp;personDao.get(person.getId()); &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertEquals(&lt;span class=&quot;string&quot;&gt;&amp;quot;Country&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;person.getFirstName()); &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertNotNull(person.getId()); &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;removing&amp;nbsp;person...&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;personDao.remove(person.getId()); &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;flush(); &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt;&lt;span&gt;&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;personDao.get(person.getId()); &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fail(&lt;span class=&quot;string&quot;&gt;&amp;quot;Person&amp;nbsp;found&amp;nbsp;in&amp;nbsp;database&amp;quot;&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;catch&lt;/span&gt;&lt;span&gt;&amp;nbsp;(DataAccessException&amp;nbsp;dae)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;log&lt;/span&gt;&lt;span&gt;.debug(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Expected&amp;nbsp;exception:&amp;nbsp;&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;dae.getMessage()); &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertNotNull(dae); &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;}&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;import org.springframework.dao.DataAccessException;
public void testAddAndRemovePerson() throws Exception {
Person person = new Person();
person.setFirstName(&amp;quot;Country&amp;quot;);
person.setLastName(&amp;quot;Bry&amp;quot;);
person = personDao.save(person);
flush();
person = personDao.get(person.getId());
assertEquals(&amp;quot;Country&amp;quot;, person.getFirstName());
assertNotNull(person.getId());
log.debug(&amp;quot;removing person...&amp;quot;);
personDao.remove(person.getId());
flush();
try {
personDao.get(person.getId());
fail(&amp;quot;Person found in database&amp;quot;);
} catch (DataAccessException dae) {
log.debug(&amp;quot;Expected exception: &amp;quot; + dae.getMessage());
assertNotNull(dae);
}
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;In the above example, you can see that person.set*(value) is being called to populate the Person object before saving it. This is easy in this example, but it could get quite cumbersome if you're persisting an object with 10 required fields. This is why a ResourceBundle exists in &lt;tt&gt;BaseDaoTestCase&lt;/tt&gt;. Simply create a &lt;tt&gt;PersonDaoTest.properties&lt;/tt&gt; file in the same directory as &lt;tt&gt;PersonDaoTest.java&lt;/tt&gt; and define your property values inside it:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;firstName=Matt &amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;lastName=Raible&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;firstName=Matt
lastName=Raible&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;
&lt;table class=&quot;tipMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/check.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;
            &lt;p&gt;I tend to just hard-code test values into Java code - but the .properties file is an option that works great for large objects.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;Then, rather than calling person.set* to populate your objects, you can use the &lt;tt&gt;BaseDaoTestCase.populate(java.lang.Object)&lt;/tt&gt; method:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;Person&amp;nbsp;person&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Person(); &amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;person&amp;nbsp;=&amp;nbsp;(Person)&amp;nbsp;populate(person);&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;Person person = new Person();
person = (Person) populate(person);&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;At this point, the &lt;tt&gt;PersonDaoTest&lt;/tt&gt; class won't compile yet because there is no &lt;tt&gt;PersonDao.class&lt;/tt&gt; in your classpath, you need to create it. &lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;UsingHibernate-CreateaDAOInterfaceandimplementation&quot;&gt;&lt;/a&gt;Create a DAO Interface and implementation &lt;a name=&quot;UsingHibernate-daoimpl&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Create a &lt;tt&gt;PersonDao.java&lt;/tt&gt; interface in the &lt;em&gt;src/main/java/**/dao&lt;/em&gt; (or &lt;em&gt;core/src/main/java/**/dao&lt;/em&gt; for a modular archetype) directory and specify the finder method for any implementation classes.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.dao; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.dao.GenericDao; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.model.Person; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;java.util.List; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;interface&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonDao&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;GenericDao&amp;lt;Person,&amp;nbsp;Long&amp;gt;&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;List&amp;lt;Person&amp;gt;&amp;nbsp;findByLastName(String&amp;nbsp;lastName); &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;}&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;package org.appfuse.tutorial.dao;
import org.appfuse.dao.GenericDao;
import org.appfuse.tutorial.model.Person;
import java.util.List;
public interface PersonDao extends GenericDao&amp;lt;Person, Long&amp;gt; {
public List&amp;lt;Person&amp;gt; findByLastName(String lastName);
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Notice in the class above there is no exception on the method signature. This is due to the power of &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.springframework.org/&quot;&gt;Spring&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; and how it wraps Exceptions with RuntimeExceptions. At this point, you should be able to compile all your code using your IDE or &lt;strong&gt;mvn test-compile&lt;/strong&gt;. However, if you try to run &lt;strong&gt;mvn test -Dtest=PersonDaoTest&lt;/strong&gt;, you will get an error:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;Running&amp;nbsp;org.appfuse.tutorial.dao.PersonDaoTest &amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;INFO&amp;nbsp;-&amp;nbsp;AbstractSingleSpringContextTests.loadContextLocations(179)&amp;nbsp;|&amp;nbsp;Loading&amp;nbsp;context&amp;nbsp;for:&amp;nbsp;classpath*:/applicationContext-*.xml &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;Tests&amp;nbsp;run:&amp;nbsp;2,&amp;nbsp;Failures:&amp;nbsp;0,&amp;nbsp;Errors:&amp;nbsp;2,&amp;nbsp;Skipped:&amp;nbsp;0,&amp;nbsp;Time&amp;nbsp;elapsed:&amp;nbsp;0.449&amp;nbsp;sec&amp;nbsp;&amp;lt;&amp;lt;&amp;lt;&amp;nbsp;FAILURE!&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;Running org.appfuse.tutorial.dao.PersonDaoTest
INFO - AbstractSingleSpringContextTests.loadContextLocations(179) | Loading context for: classpath*:/applicationContext-*.xml
Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 0.449 sec &amp;lt;&amp;lt;&amp;lt; FAILURE!&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Unfortunately, this doesn't tell you much about what went wrong. To find the real problem, you need to open &lt;em&gt;target/surefire-reports/org.appfuse.tutorial.dao.PersonDaoTest.txt&lt;/em&gt; (or &lt;em&gt;core/target/surefire-reports/org.appfuse.tutorial.dao.PersonDaoTest.txt&lt;/em&gt; for a modular archetype). In this file, the real problem is shown:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;------------------------------------------------------------------------------- &amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;Test&amp;nbsp;set:&amp;nbsp;org.appfuse.tutorial.dao.PersonDaoTest &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;------------------------------------------------------------------------------- &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;Tests&amp;nbsp;run:&amp;nbsp;2,&amp;nbsp;Failures:&amp;nbsp;0,&amp;nbsp;Errors:&amp;nbsp;2,&amp;nbsp;Skipped:&amp;nbsp;0,&amp;nbsp;Time&amp;nbsp;elapsed:&amp;nbsp;0.444&amp;nbsp;sec&amp;nbsp;&amp;lt;&amp;lt;&amp;lt;&amp;nbsp;FAILURE! &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;testFindPersonByLastName(org.appfuse.tutorial.dao.PersonDaoTest)&amp;nbsp;&amp;nbsp;Time&amp;nbsp;elapsed:&amp;nbsp;0.401&amp;nbsp;sec&amp;nbsp;&amp;nbsp;&amp;lt;&amp;lt;&amp;lt;&amp;nbsp;ERROR! &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;org.springframework.beans.factory.UnsatisfiedDependencyException:&amp;nbsp;Error&amp;nbsp;creating&amp;nbsp;bean&amp;nbsp; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;with&amp;nbsp;name&amp;nbsp;&lt;span class=&quot;string&quot;&gt;'org.appfuse.tutorial.dao.PersonDaoTest'&lt;/span&gt;&lt;span&gt;:&amp;nbsp;Unsatisfied&amp;nbsp;dependency&amp;nbsp;expressed&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;through&amp;nbsp;bean&amp;nbsp;property&amp;nbsp;&lt;span class=&quot;string&quot;&gt;'personDao'&lt;/span&gt;&lt;span&gt;:&amp;nbsp;Set&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;&amp;nbsp;property&amp;nbsp;value&amp;nbsp;or&amp;nbsp;disable&amp;nbsp;dependency&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;checking&amp;nbsp;for&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;bean.&lt;/font&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;-------------------------------------------------------------------------------
Test set: org.appfuse.tutorial.dao.PersonDaoTest
-------------------------------------------------------------------------------
Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 0.444 sec &amp;lt;&amp;lt;&amp;lt; FAILURE!
testFindPersonByLastName(org.appfuse.tutorial.dao.PersonDaoTest)  Time elapsed: 0.401 sec  &amp;lt;&amp;lt;&amp;lt; ERROR!
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean
with name 'org.appfuse.tutorial.dao.PersonDaoTest': Unsatisfied dependency expressed
through bean property 'personDao': Set this property value or disable dependency
checking for this bean.&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;
&lt;table class=&quot;tipMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/check.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Showing errors in your console&lt;/strong&gt;&lt;br /&gt;To show testing errors in your console, append &lt;strong&gt;-Dsurefire.useFile=false&lt;/strong&gt; to your &lt;strong&gt;mvn test&lt;/strong&gt; command.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;This is an error message from Spring - indicating that you need to specify a bean named &amp;quot;personDao&amp;quot; in a Spring context file. Before you do that, you need to create the &lt;tt&gt;PersonDao&lt;/tt&gt; implementation.&lt;/p&gt;
&lt;p&gt;Create a &lt;tt&gt;PersonDaoHibernate&lt;/tt&gt; class that implements the finder method in &lt;tt&gt;PersonDao&lt;/tt&gt;. To do this, create a new class in &lt;em&gt;src/main/java/**/dao/hibernate&lt;/em&gt; (or &lt;em&gt;core/src/main/java/**/dao/hibernate&lt;/em&gt; for the modular archetype) and name it &lt;tt&gt;PersonDaoHibernate.java&lt;/tt&gt;. It should extend &lt;tt&gt;GenericDaoHibernate&lt;/tt&gt; and implement &lt;tt&gt;PersonDao&lt;/tt&gt;. &lt;em&gt;Javadocs eliminated for brevity.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.dao.hibernate; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;java.util.List; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.dao.hibernate.GenericDaoHibernate; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.model.Person; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.dao.PersonDao; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonDaoHibernate&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;GenericDaoHibernate&amp;lt;Person,&amp;nbsp;Long&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;implements&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonDao&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;PersonDaoHibernate()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;super(Person.&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;); &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;List&amp;lt;Person&amp;gt;&amp;nbsp;findByLastName(String&amp;nbsp;lastName)&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;getHibernateTemplate().find(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;from&amp;nbsp;Person&amp;nbsp;where&amp;nbsp;lastName=?&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;lastName); &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;}&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;package org.appfuse.tutorial.dao.hibernate;
import java.util.List;
import org.appfuse.dao.hibernate.GenericDaoHibernate;
import org.appfuse.tutorial.model.Person;
import org.appfuse.tutorial.dao.PersonDao;
public class PersonDaoHibernate extends GenericDaoHibernate&amp;lt;Person, Long&amp;gt; implements PersonDao {
public PersonDaoHibernate() {
super(Person.class);
}
public List&amp;lt;Person&amp;gt; findByLastName(String lastName) {
return getHibernateTemplate().find(&amp;quot;from Person where lastName=?&amp;quot;, lastName);
}
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Now, if you try to run &lt;strong&gt;mvn test -Dtest=PersonDaoTest&lt;/strong&gt;, you will get the same error. You need to configure Spring so it knows that &lt;tt&gt;PersonDaoHibernate&lt;/tt&gt; is the implementation of &lt;tt&gt;PersonDao&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Create an &lt;tt&gt;applicationContext.xml&lt;/tt&gt; file in &lt;em&gt;src/main/webapp/WEB-INF&lt;/em&gt; (or &lt;em&gt;core/src/main/resources&lt;/em&gt; for a modular archetype) and add the following XML to it:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;0&quot; class=&quot;dp-c&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&lt;span&gt;&amp;lt;?xml&amp;nbsp;version=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;encoding=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span&gt;?&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;lt;beans&amp;nbsp;xmlns=&lt;span class=&quot;string&quot;&gt;&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:xsi=&lt;span class=&quot;string&quot;&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xsi:schemaLocation=&amp;quot;http:&lt;span class=&quot;comment&quot;&gt;//www.springframework.org/schema/beans &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;http:&lt;span class=&quot;comment&quot;&gt;//www.springframework.org/schema/beans/spring-beans-2.0.xsd&amp;quot;&amp;gt; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;bean&amp;nbsp;id=&lt;span class=&quot;string&quot;&gt;&amp;quot;personDao&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.tutorial.dao.hibernate.PersonDaoHibernate&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property&amp;nbsp;name=&lt;span class=&quot;string&quot;&gt;&amp;quot;sessionFactory&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;ref=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;sessionFactory&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/bean&amp;gt;&amp;nbsp; &amp;nbsp;&lt;/font&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;font style=&quot;BACKGROUND-COLOR: #ccffcc&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/font&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;
xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd&amp;quot;&amp;gt;
&amp;lt;bean id=&amp;quot;personDao&amp;quot; class=&amp;quot;org.appfuse.tutorial.dao.hibernate.PersonDaoHibernate&amp;quot;&amp;gt;
&amp;lt;property name=&amp;quot;sessionFactory&amp;quot; ref=&amp;quot;sessionFactory&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;
&amp;lt;/beans&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;UsingHibernate-RuntheDAOTest&quot;&gt;&lt;/a&gt;Run the DAO Test &lt;a name=&quot;UsingHibernate-runtest&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Save all your edited files and try running &lt;strong&gt;mvn test -Dtest=PersonDaoTest&lt;/strong&gt; one more time. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yeah Baby, Yeah:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;COLOR: green&quot;&gt;BUILD SUCCESSFUL&lt;br clear=&quot;all&quot; /&gt;Total time: 9 seconds&lt;/span&gt; &lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;Next Up:&lt;/em&gt; &lt;strong&gt;Part II:&lt;/strong&gt; &lt;a title=&quot;Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services&quot;&gt;Creating new Managers&lt;/a&gt; - A HowTo for creating Business Facades, which are similar to &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://java.sun.com/blueprints/patterns/SessionFacade.html&quot;&gt;Session Facades&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;, but don't use EJBs. These facades are used to provide communication from the front-end to the DAO layer.&lt;/p&gt;
&lt;!--
&lt;rdf:RDF xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;
xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot;
xmlns:trackback=&quot;http://madskills.com/public/xml/rss/module/trackback/&quot;&gt;
&lt;rdf:Description
rdf:about=&quot;http://appfuse.org/display/APF/Using+Hibernate&quot;
dc:identifier=&quot;http://appfuse.org/display/APF/Using+Hibernate&quot;
dc:title=&quot;Using Hibernate&quot;
trackback:ping=&quot;http://appfuse.org/rpc/trackback/28&quot; /&gt;
&lt;/rdf:RDF&gt;
--&gt;
            &lt;div&gt;
                作者：xiong2009 发表于2007-8-23 19:03:00 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1756515&quot;&gt;原文链接&lt;/a&gt;
            &lt;/div&gt;
            &lt;div&gt;
            阅读：916 评论：0 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1756515#comments&quot; target=&quot;_blank&quot;&gt;查看评论&lt;/a&gt;
            &lt;/div&gt;</description><pubDate>Thu, 23 Aug 2007 19:03:00 +0800</pubDate><author>xiong2009</author><guid isPermaLink="false">http://blog.csdn.net/xiong2009/article/details/1756515</guid><dc:creator>xiong2009</dc:creator><fs:srclink>http://blog.csdn.net/xiong2009/article/details/1756515</fs:srclink><fs:srcfeed>http://blog.csdn.net/xiong2009/Rss.aspx</fs:srcfeed><fs:itemid>feedsky/xiong2009/~1212304/602964773/1227063</fs:itemid></item><item><title>[原]appFuse2.x第三篇--Persistence</title><link>http://blog.csdn.net/xiong2009/article/details/1756512</link><description>&lt;p&gt;This tutorial will show you how to create a new database table and the Java code to access that table. &lt;/p&gt;
&lt;p&gt;You will create an object and then some more classes to persist (save/retrieve/delete) that object from the database. In Java speak, this object is called a Plain Old Java Object (&lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://en.wikipedia.org/wiki/Plain_Old_Java_Object&quot;&gt;POJO&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;). This object basically represents a database table. With AppFuse 1.x, you typically created a &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://java.sun.com/blueprints/patterns/DAO.html&quot;&gt;DAO&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; and &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.junit.org/&quot;&gt;JUnit&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; Test to persist this POJO. However, with AppFuse 2.x, there is a Generics-based DAO and Manager that will CRUD all objects for you. The only time you'll need to create DAOs is when you want custom behavior or if you need finders. &lt;/p&gt;
&lt;p&gt;AppFuse uses &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.hibernate.org/&quot;&gt;Hibernate&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; for its default persistence layer. Hibernate is an Object/Relational (O/R) Framework that allows you to relate your Java Objects to database tables. It allows you to very easily perform CRUD (Create, Retrieve, Update, Delete) on your objects. &lt;/p&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;iBATIS and JPA&lt;/strong&gt;&lt;br /&gt;You can also use &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://ibatis.com/&quot;&gt;iBATIS&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; or &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://java.sun.com/developer/technicalArticles/J2EE/jpa/&quot;&gt;JPA&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; as a persistence framework option. To use iBATIS with AppFuse, see the &lt;a title=&quot;Using iBATIS&quot; href=&quot;http://www.appfuse.org/display/APF/Using+iBATIS&quot;&gt;using iBATIS&lt;/a&gt; tutorial. To use JPA implementation, see the &lt;a title=&quot;Using JPA&quot; href=&quot;http://www.appfuse.org/display/APF/Using+JPA&quot;&gt;using JPA&lt;/a&gt; tutorial.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To get started creating a new Object and table in AppFuse's project structure, please complete the instructions below. &lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;Persistence-TableofContents&quot;&gt;&lt;/a&gt;Table of Contents&lt;/h3&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;a title=&quot;createpojo on Persistence&quot; href=&quot;http://www.appfuse.org/display/APF/Persistence#Persistence-createpojo&quot;&gt;Create a new POJO and add JPA Annotations&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a title=&quot;createschema on Persistence&quot; href=&quot;http://www.appfuse.org/display/APF/Persistence#Persistence-createschema&quot;&gt;Create a new database table from the object using Maven&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;&lt;a name=&quot;Persistence-CreateanewPOJOandaddJPAAnnotations&quot;&gt;&lt;/a&gt;Create a new POJO and add JPA Annotations &lt;a name=&quot;Persistence-createpojo&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first thing you need to do is create an object to persist. Create a simple &amp;quot;Person&amp;quot; object (in the &lt;em&gt;src/main/java/**/model&lt;/em&gt; directory for the basic archetypes or the &lt;em&gt;core/src/main/java/**/model&lt;/em&gt; directory for the modular archetypes) that has an id, a firstName and a lastName (as properties). For recommend package-naming conventions, see the &lt;a title=&quot;packagenaming on FAQ&quot; href=&quot;http://www.appfuse.org/display/APF/FAQ#FAQ-packagenaming&quot;&gt;FAQ&lt;/a&gt;. These tutorials use &amp;quot;org.appfuse.tutorial&amp;quot; as the root package name.&lt;/p&gt;
&lt;style type=&quot;text/css&quot;&gt;

@import url( /download/resources/confluence.ext.code:code/shStyles.css );&lt;/style&gt;&lt;style type=&quot;text/css&quot;&gt;

.code TEXTAREA {
	PADDING-RIGHT: 0px! important; PADDING-LEFT: 0px! important; PADDING-BOTTOM: 0px! important; PADDING-TOP: 0px! important
}
.code INPUT {
	PADDING-RIGHT: 0px! important; PADDING-LEFT: 0px! important; PADDING-BOTTOM: 0px! important; PADDING-TOP: 0px! important
}&lt;/style&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shCore.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushCSharp.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushPhp.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushJScript.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushVb.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushSql.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushXml.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushShell.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushDelphi.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushPython.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script class=&quot;javascript&quot; src=&quot;/download/resources/confluence.ext.code:code/shBrushJava.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.tutorial.model; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;org.appfuse.model.BaseObject; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;javax.persistence.Entity; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;javax.persistence.GenerationType; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;javax.persistence.Id; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;javax.persistence.GeneratedValue; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;javax.persistence.Column; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;Person&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BaseObject&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;Long&amp;nbsp;id; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;firstName; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;lastName; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;comment&quot;&gt;/* &lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;comment&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Generate&amp;nbsp;your&amp;nbsp;getters&amp;nbsp;and&amp;nbsp;setters&amp;nbsp;using&amp;nbsp;your&amp;nbsp;favorite&amp;nbsp;IDE:&amp;nbsp; &lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;comment&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;In&amp;nbsp;Eclipse: &lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;comment&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Right-click&amp;nbsp;-&amp;gt;&amp;nbsp;Source&amp;nbsp;-&amp;gt;&amp;nbsp;Generate&amp;nbsp;Getters&amp;nbsp;and&amp;nbsp;Setters &lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;comment&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;package org.appfuse.tutorial.model;
import org.appfuse.model.BaseObject;
import javax.persistence.Entity;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.Column;
public class Person extends BaseObject {
private Long id;
private String firstName;
private String lastName;
/*
Generate your getters and setters using your favorite IDE:
In Eclipse:
Right-click -&amp;gt; Source -&amp;gt; Generate Getters and Setters
*/
}&lt;/textarea&gt;&lt;/div&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;Extending BaseObject is optional, but recommended as a good practice to force creation of &lt;tt&gt;toString()&lt;/tt&gt;, &lt;tt&gt;equals()&lt;/tt&gt; and &lt;tt&gt;hashCode()&lt;/tt&gt; methods. If you plan to put this object into the user's session, or expose it through a web service, you should implement &lt;tt&gt;java.io.Serializable&lt;/tt&gt; as well.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To generate &lt;tt&gt;toString()&lt;/tt&gt;, &lt;tt&gt;equals()&lt;/tt&gt; and &lt;tt&gt;hashCode()&lt;/tt&gt; methods, you can use &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://commonclipse.sf.net/&quot;&gt;Commonclipse&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. More information on using this tool can be found on &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.leegrey.com/hmm/2004/09/29/1096491256000.html&quot;&gt;Lee Grey's site&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. Another Eclipse Plugin you can use is &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://commons4e.berlios.de/&quot;&gt;Commons4E&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. When generating or writing &lt;tt&gt;equals()&lt;/tt&gt; and &lt;tt&gt;hashCode()&lt;/tt&gt; methods, you don't want to include your object's primary key. See Hibernate's &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.hibernate.org/109.html&quot;&gt;Equals and Hascode&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; for more information.&lt;/p&gt;
&lt;table class=&quot;infoMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/information.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;IntelliJ Users&lt;/strong&gt;&lt;br /&gt;If you're using &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.jetbrains.com/idea&quot;&gt;IntelliJ IDEA&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;, you can generate equals() and hashCode(), but not toString(). There is a &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.intellij.org/twiki/bin/view/Main/ToStringPlugin&quot;&gt;ToStringPlugin&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; that works reasonably well.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Now that you have this POJO created, you need to add &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html&quot;&gt;JPA annotations&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. These annotations are used by Hibernate to map objects &amp;rarr; tables and properties (variables) &amp;rarr; columns. &lt;/p&gt;
&lt;table class=&quot;tipMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/check.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;If you're new to Hibernate and Annotations, you might want to read &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.onjava.com/pub/a/onjava/2007/02/08/an-introduction-to-hibernate-3-annotations.html&quot;&gt;An Introduction to Hibernate 3 Annotations&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; by John Ferguson Smart.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;First of all, add an &lt;tt&gt;@Entity&lt;/tt&gt; annotation that signifies what table this object relates to. The &amp;quot;name&amp;quot; is optional; the class name is used if it's not specified. Make sure you import annotations from &lt;tt&gt;javax.persistence.*&lt;/tt&gt; rather than from Hibernate.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt;@Entity &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;Person&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BaseObject&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;@Entity
public class Person extends BaseObject {&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;table class=&quot;noteMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/warning.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;If you specify a name value for your &lt;tt&gt;@Entity&lt;/tt&gt; annotation (for example &lt;tt&gt;@Entity(name=&amp;quot;person&amp;quot;)&lt;/tt&gt;), this will be the alias for HQL queries. If you don't specify this value, the name will match the short name of your class (&lt;tt&gt;Person&lt;/tt&gt;). If you want to change the table name that's generated, use the &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://java.sun.com/javaee/5/docs/api/javax/persistence/Table.html&quot;&gt;@Table&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; annotation with a &amp;quot;name&amp;quot; value.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You also have to add an &lt;tt&gt;@Id&lt;/tt&gt; annotation to signify the primary key. The &lt;tt&gt;@GeneratedValue&lt;/tt&gt; annotation should also be specified to indicate the primary key generation strategy.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt;@Id&amp;nbsp;@GeneratedValue(strategy&amp;nbsp;=&amp;nbsp;GenerationType.AUTO)&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;Long&amp;nbsp;getId()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.id; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;@Id @GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return this.id;
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;For the rest of the fields, you aren't required to annotate them unless you want to 1) exclude them from being persisted (with &lt;tt&gt;@Transient&lt;/tt&gt;) or 2) want to change their column name or other attributes. To change the column names, use the &lt;tt&gt;@Column&lt;/tt&gt; annotation. Add the &lt;tt&gt;@Column&lt;/tt&gt; annotation to both the &lt;em&gt;getFirstName()&lt;/em&gt; and &lt;em&gt;getLastName()&lt;/em&gt; methods.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;preprocessor&quot;&gt;@Column(name=&amp;quot;first_name&amp;quot;,&amp;nbsp;length=50) &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;getFirstName()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.firstName; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;} &amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;... &lt;span class=&quot;preprocessor&quot;&gt;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&lt;span class=&quot;preprocessor&quot;&gt;@Column(name=&amp;quot;last_name&amp;quot;,&amp;nbsp;length=50) &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;getLastName()&amp;nbsp;{ &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;&lt;span&gt;.lastName; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;}&amp;nbsp;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;@Column(name=&amp;quot;first_name&amp;quot;, length=50)
public String getFirstName() {
return this.firstName;
}
...
@Column(name=&amp;quot;last_name&amp;quot;, length=50)
public String getLastName() {
return this.lastName;
}&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;table class=&quot;warningMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/forbidden.gif&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Annotations on fields&lt;/strong&gt;&lt;br /&gt;You can also put JPA annotations on fields instead of &lt;em&gt;getters&lt;/em&gt;. However, you should be aware that if you add field-level annotations, &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://jroller.com/page/chemeia?entry=mystery_of_the_ignored_persistence&quot;&gt;method-level annotations will be ignored&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;&lt;a name=&quot;Persistence-CreateanewdatabasetablefromtheobjectusingMaven&quot;&gt;&lt;/a&gt;Create a new database table from the object using Maven &lt;a name=&quot;Persistence-createschema&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Open &lt;em&gt;src/main/resources/hibernate.cfg.xml&lt;/em&gt; for the basic archetypes (or &lt;em&gt;core/src/main/resources/hibernate.cfg.xml&lt;/em&gt; for the modular archetypes) and register your Person object with the following XML:&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;&amp;lt;mapping&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;org.appfuse.tutorial.model.Person&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;&amp;lt;mapping class=&amp;quot;org.appfuse.tutorial.model.Person&amp;quot;/&amp;gt;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;Save the file and run &lt;strong&gt;mvn test-compile hibernate3:hbm2ddl&lt;/strong&gt; from the command line. For modular projects, make sure you run this command from the &amp;quot;core&amp;quot; directory. This will generate your database schema with the &amp;quot;person&amp;quot; table included.&lt;/p&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;div class=&quot;dp-highlighter&quot;&gt;
&lt;table class=&quot;dp-c&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;line1&quot;&gt;&lt;span&gt;create&amp;nbsp;table&amp;nbsp;person&amp;nbsp;(id&amp;nbsp;bigint&amp;nbsp;not&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;null&lt;/span&gt;&lt;span&gt;&amp;nbsp;auto_increment,&amp;nbsp;first_name&amp;nbsp;varchar(50),&amp;nbsp;primary&amp;nbsp;key&amp;nbsp;(id))&amp;nbsp;type=InnoDB;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;textarea class=&quot;java:nocontrols:nogutter&quot; style=&quot;DISPLAY: none&quot; rows=&quot;10&quot; readonly=&quot;readonly&quot; name=&quot;newcodemacro&quot;&gt;create table person (id bigint not null auto_increment, first_name varchar(50), primary key (id)) type=InnoDB;&lt;/textarea&gt; &lt;script class=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt;
    if(!window.newcodemacro_initialised)
    {
        window.newcodemacro_initialised = true;
        window.oldonloadmethod = window.onload;
        window.onload = function(){
            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
            if(window.oldonloadmethod)
            {
                window.oldonloadmethod();
            }
        }
    }

&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;After you've created a POJO and generated a schema from it, how do you persist that object? AppFuse ships with GenericDao implementations that makes it possible CRUD any object. In addition to this &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html&quot;&gt;Generics&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;-based class, there is a UniversalDao that does the same thing. The major difference between the two is you'll need to cast to your specified type for the UniversalDao. However, it also doesn't require you to define any new Spring beans, so there's a benefits and drawbacks. For these tutorials, you will learn how to program using the GenericDao.&lt;/p&gt;
&lt;p&gt;Please choose the persistence framework you'd like to use to continue:&lt;/p&gt;
&lt;div style=&quot;MARGIN-LEFT: 40px&quot;&gt;&lt;a title=&quot;Using Hibernate&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Hibernate&quot;&gt;&lt;img alt=&quot;&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/download/attachments/27/hibernate-logo.gif&quot; /&gt;&lt;/a&gt; &lt;a title=&quot;Using iBATIS&quot; href=&quot;http://www.appfuse.org/display/APF/Using+iBATIS&quot;&gt;&lt;img alt=&quot;&quot; hspace=&quot;30&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/download/attachments/27/ibatis-logo.jpg&quot; /&gt;&lt;/a&gt; &lt;a title=&quot;Using JPA&quot; href=&quot;http://www.appfuse.org/display/APF/Using+JPA&quot;&gt;&lt;img alt=&quot;&quot; hspace=&quot;30&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/download/attachments/27/jpa-logo.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;If you don't know which is better for your project, please read &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://raibledesigns.com/page/rd?entry=hibernate_vs_ibatis&quot;&gt;Hibernate vs. iBATIS&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;!--
&lt;rdf:RDF xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;
xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot;
xmlns:trackback=&quot;http://madskills.com/public/xml/rss/module/trackback/&quot;&gt;
&lt;rdf:Description
rdf:about=&quot;http://appfuse.org/display/APF/Persistence&quot;
dc:identifier=&quot;http://appfuse.org/display/APF/Persistence&quot;
dc:title=&quot;Persistence&quot;
trackback:ping=&quot;http://appfuse.org/rpc/trackback/27&quot; /&gt;
&lt;/rdf:RDF&gt;
--&gt;&amp;nbsp;
            &lt;div&gt;
                作者：xiong2009 发表于2007-8-23 19:01:00 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1756512&quot;&gt;原文链接&lt;/a&gt;
            &lt;/div&gt;
            &lt;div&gt;
            阅读：818 评论：0 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1756512#comments&quot; target=&quot;_blank&quot;&gt;查看评论&lt;/a&gt;
            &lt;/div&gt;</description><pubDate>Thu, 23 Aug 2007 19:01:00 +0800</pubDate><author>xiong2009</author><guid isPermaLink="false">http://blog.csdn.net/xiong2009/article/details/1756512</guid><dc:creator>xiong2009</dc:creator><fs:srclink>http://blog.csdn.net/xiong2009/article/details/1756512</fs:srclink><fs:srcfeed>http://blog.csdn.net/xiong2009/Rss.aspx</fs:srcfeed><fs:itemid>feedsky/xiong2009/~1212304/602964774/1227063</fs:itemid></item><item><title>[原]appFuse2.x第二篇</title><link>http://blog.csdn.net/xiong2009/article/details/1756508</link><description>&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;pagebody&quot; valign=&quot;top&quot;&gt;
            &lt;table style=&quot;CLEAR: both&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot;&gt;
                &lt;tbody&gt;
                    &lt;tr&gt;
                        &lt;td class=&quot;pagecontent&quot; valign=&quot;top&quot; width=&quot;100%&quot;&gt;
                        &lt;div class=&quot;wiki-content&quot;&gt;&lt;!-- wiki content --&gt;
                        &lt;p&gt;Tutorials for AppFuse 2.x are a work in progress. To develop an application with AppFuse, you generally create &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://en.wikipedia.org/wiki/Plain_Old_Java_Object&quot;&gt;POJOs&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; and configure how they work with &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.springframework.org/&quot;&gt;Spring&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. Follow the steps below to create a master/detail screens that CRUD a Person object. You should create a project using the &lt;a title=&quot;AppFuse QuickStart&quot; href=&quot;http://www.appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; and setup your &lt;a title=&quot;Development Environment&quot; href=&quot;http://www.appfuse.org/display/APF/Development+Environment&quot;&gt;development environment&lt;/a&gt; before starting these tutorials.&lt;/p&gt;
                        &lt;ol&gt;
                            &lt;li&gt;Create a &lt;a title=&quot;Persistence&quot; href=&quot;http://www.appfuse.org/display/APF/Persistence&quot;&gt;Person Entity&lt;/a&gt;. &lt;/li&gt;
                            &lt;li&gt;Create a &lt;tt&gt;PersonDao&lt;/tt&gt; in &lt;a title=&quot;Using Hibernate&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Hibernate&quot;&gt;Hibernate&lt;/a&gt;, &lt;a title=&quot;Using iBATIS&quot; href=&quot;http://www.appfuse.org/display/APF/Using+iBATIS&quot;&gt;iBATIS&lt;/a&gt; or &lt;a title=&quot;Using JPA&quot; href=&quot;http://www.appfuse.org/display/APF/Using+JPA&quot;&gt;JPA&lt;/a&gt;. &lt;/li&gt;
                            &lt;li&gt;Create a &lt;a title=&quot;Services&quot; href=&quot;http://www.appfuse.org/display/APF/Services&quot;&gt;PersonManager&lt;/a&gt; to act as a service facade to &lt;tt&gt;PersonDao&lt;/tt&gt;. &lt;/li&gt;
                            &lt;li&gt;Create the web tier using &lt;a title=&quot;Using JSF&quot; href=&quot;http://www.appfuse.org/display/APF/Using+JSF&quot;&gt;JSF&lt;/a&gt;, &lt;a title=&quot;Using Struts 2&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Struts+2&quot;&gt;Struts 2&lt;/a&gt;, &lt;a title=&quot;Using Spring MVC&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Spring+MVC&quot;&gt;Spring MVC&lt;/a&gt; or &lt;a title=&quot;Using Tapestry&quot; href=&quot;http://www.appfuse.org/display/APF/Using+Tapestry&quot;&gt;Tapestry&lt;/a&gt;. &lt;/li&gt;
                        &lt;/ol&gt;
                        &lt;p&gt;&lt;strong&gt;Where's the source?&lt;/strong&gt;&lt;br /&gt;One of the most commonly asked questions about AppFuse 2.x is &lt;a title=&quot;whereisthesource on FAQ&quot; href=&quot;http://www.appfuse.org/display/APF/FAQ#FAQ-whereisthesource&quot;&gt;where's the source&lt;/a&gt;? If you'd like to convert your project so it doesn't rely on AppFuse dependencies and includes AppFuse's source instead, run &lt;strong&gt;mvn appfuse:full-source&lt;/strong&gt;. This feature is only available in 2.0 M5+ and currently only works with basic archetypes. &lt;/p&gt;
                        &lt;p&gt;&lt;strong&gt;CRUD Generation&lt;/strong&gt;&lt;br /&gt;AppFuse has a &lt;a title=&quot;Maven Plugins&quot; href=&quot;http://www.appfuse.org/display/APF/Maven+Plugins&quot;&gt;Maven Plugin&lt;/a&gt; that allows you to generate all the code in these tutorials. However, we recommend you complete these tutorials before using it so you're familiar with all the code that's being generated.&lt;/p&gt;
                        &lt;p&gt;One of the nice features of AppFuse 2.x is you no longer need to create a DAO or Manager for type-safe CRUD functionality. You merely need to create Spring bean definitions. This means you should be able to easily develop a front-end without worrying about writing code for the backend (until you need customized functionality of course).&lt;/p&gt;
                        &lt;table class=&quot;tipMacro&quot; cellspacing=&quot;8&quot; cellpadding=&quot;5&quot; width=&quot;85%&quot; align=&quot;center&quot; summary=&quot;&quot; border=&quot;1&quot;&gt;
                            &lt;colgroup&gt;&lt;col width=&quot;24&quot;&gt;&lt;/col&gt;&lt;col&gt;&lt;/col&gt;&lt;/colgroup&gt;
                            &lt;tbody&gt;
                                &lt;tr&gt;
                                    &lt;td valign=&quot;top&quot;&gt;&lt;img height=&quot;16&quot; alt=&quot;&quot; width=&quot;16&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/emoticons/check.gif&quot; /&gt;&lt;/td&gt;
                                    &lt;td&gt;&lt;strong class=&quot;strong&quot;&gt;Having trouble choosing a web framework?&lt;/strong&gt;&lt;br /&gt;If you're having trouble choosing a web framework, read &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://raibledesigns.com/page/rd?entry=re_what_web_application_framework&quot;&gt;What Web Application framework should you use?&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt; and &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;http://www.virtuas.com/articles/webframework-sweetspots.html&quot;&gt;Java Web Framework Sweet Spots&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;. More information on comparing web frameworks can be found at &lt;span class=&quot;nobr&quot;&gt;&lt;a title=&quot;Visit page outside Confluence&quot; rel=&quot;nofollow&quot; href=&quot;https://appfuse-light.dev.java.net/framework-comparison&quot;&gt;https://appfuse-light.dev.java.net/framework-comparison&lt;sup&gt;&lt;img class=&quot;rendericon&quot; height=&quot;7&quot; alt=&quot;&quot; width=&quot;7&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; src=&quot;http://www.appfuse.org/images/icons/linkext7.gif&quot; /&gt;&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;.&lt;/td&gt;
                                &lt;/tr&gt;
                            &lt;/tbody&gt;
                        &lt;/table&gt;
                        &lt;/div&gt;
                        &lt;!--
                        &lt;rdf:RDF xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot;
                        xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot;
                        xmlns:trackback=&quot;http://madskills.com/public/xml/rss/module/trackback/&quot;&gt;
                        &lt;rdf:Description
                        rdf:about=&quot;http://appfuse.org/display/APF/Tutorials&quot;
                        dc:identifier=&quot;http://appfuse.org/display/APF/Tutorials&quot;
                        dc:title=&quot;Tutorials&quot;
                        trackback:ping=&quot;http://appfuse.org/rpc/trackback/8&quot; /&gt;
                        &lt;/rdf:RDF&gt;
                        --&gt;&lt;/td&gt;
                    &lt;/tr&gt;
                &lt;/tbody&gt;
            &lt;/table&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&amp;nbsp;
            &lt;div&gt;
                作者：xiong2009 发表于2007-8-23 18:59:00 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1756508&quot;&gt;原文链接&lt;/a&gt;
            &lt;/div&gt;
            &lt;div&gt;
            阅读：946 评论：0 &lt;a href=&quot;http://blog.csdn.net/xiong2009/article/details/1756508#comments&quot; target=&quot;_blank&quot;&gt;查看评论&lt;/a&gt;
            &lt;/div&gt;</description><pubDate>Thu, 23 Aug 2007 18:59:00 +0800</pubDate><author>xiong2009</author><guid isPermaLink="false">http://blog.csdn.net/xiong2009/article/details/1756508</guid><dc:creator>xiong2009</dc:creator><fs:srclink>http://blog.csdn.net/xiong2009/article/details/1756508</fs:srclink><fs:srcfeed>http://blog.csdn.net/xiong2009/Rss.aspx</fs:srcfeed><fs:itemid>feedsky/xiong2009/~1212304/602964775/1227063</fs:itemid></item></channel></rss>
