<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>fxy1949</title>
    <description>Chinese in London.</description>
    <link>http://fxy1949.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>回复: DAO与SERVICE层的疑惑</title>
        <author>fxy1949</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fxy1949.javaeye.com">fxy1949</a>&nbsp;
          链接：<a href="http://fxy1949.javaeye.com/blog/145695" style="color:red;">http://fxy1949.javaeye.com/blog/145695</a>&nbsp;
          发表时间: 2007年12月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p class="MsoNormal" style="MARGIN: 5pt 0cm; mso-pagination: none; mso-layout-grid-align: none"><font size="3"><span lang="EN-GB" style="mso-ansi-language: EN-GB"><font face="Times New Roman">[quote=&quot;calmness&quot;] </font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">一直以来都是开发</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">EJB</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">的项目，对于</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">SSH</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">的架构仅仅只是处于了解而没实际开发过，最近正在将公司的一个</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">EJB</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">项目重构成一个</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">SSH</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">的架构，在实际开发过程中遇到了一些问题，其中一个就是持久层和业务层之间数据传输的问题。</span><span lang="ZH-CN" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman"> </font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">在原来</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">EJB</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">项目中，都是使用实体</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">BEAN</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">进行数据持久的，而现在换成了</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">DAO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">负责持久逻辑，一开始的时候业务层和持久层之间数据通信都是直接使用</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">POJO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">进行，不再需要像以前使用</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">EJB</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">那样将</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">DTO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">的数据</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">set</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">到实体</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">BEAN</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">上，减少了很多不必要的代码，刚开始的时候觉得挺爽，可是后来发现一个问题，那就是在</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">service</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">层调用</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">DAO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">持久一个</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">POJO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">后，</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">POJO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">将变成</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">PO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">，</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">DAO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">持久方法将会返回一个对象，而我目前的做法就是直接返回一个</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">PO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">到业务层，可是现在发现这种做法存在不恰当的地方，那就是</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">PO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">在业务层的话，结果就将业务层与持久层相耦合，而</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">DAO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">层的作用也因此而消弱，但是如果我不是直接返回</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">PO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">的话，那我又要构造一个</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">VO</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">返回给业务层，那这种做法不是又回到原来</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">EJB</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">的方式上？而且这样我也无法在业务层上获得</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">HIBERNATE</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">很多优化性能功能，例如</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">lazy load</font></span><span new="" arial="" lang="ZH-CN" unicode="" style="FONT-FAMILY: ">等，看了很多相关的帖子，但是好像都没有我想要的答案，请教一下我该如何解决这个问题？</span><span lang="EN-GB" style="mso-fareast-font-family: 'Arial Unicode MS'; mso-ansi-language: EN-GB"><font face="Times New Roman">[/quote]<o:p></o:p></font></span></font></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">When using SSH(Struts+Spring+Hibernate), data transform and transfer is painful, usually, from ActionForm(Web) --&gt; VO(Service) --&gt; PO(DAO) .... --&gt; <st1:place w:st="on">PO</st1:place> --&gt; VO --&gt; ActionForm. As for EJB2, it is very similar that you have to convert ActionForm(or whatever other objects depending on what web layer framework you use) into DTO(Data Transfer Object) and then into Entity Bean.<o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">However, that is the cost of layering your application, which makes your system more flexible and loosely coupled.<o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">The problem is when using the above architectures, there is too much duplication of classes and its &ldquo;getter and setter&rdquo; and too much simple &ldquo;copy&rdquo; of code. For system maintenance and extension, it&rsquo;s a nightmare.&nbsp;<span style="mso-spacerun: yes">&nbsp;</span></span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">So I would say your problem is not only about passing data from service layer into DAO layer, but also about transferring data between different layers in system. <o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">The solution probably is using POJO and new web frameworks and new Persistence APIs.&nbsp;</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">If you want to continue to use Struts and Spring, using Struts2+spring+JPA is your choice. If you are going to adopt EJB, using JSF+EJB3 is your choice. The key of both architectures is their using POJO(+Annotation) as the vehicle of data transfer and manipulation.</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">For example, JSF components can be directly bound to POJO&rsquo;s field; JPA EntityManager uses POJO+Annotion as Entity Bean to manipulate data in database. Struts2 also discarded the ActionForm and uses POJO as HTML input or output value binding.<o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">So put it simple, forget VO,DTO,PO,ActionForm, only use POJO(+Annotation),which is also called &ldquo;domain objects&rdquo;, you will find that the system becomes so clean and no any duplication for data transfer at all. <o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">Here is a very good example for Strut2+Spring+JPA:</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><a href="http://cwiki.apache.org/S2WIKI/struts-2-spring-2-jpa-ajax.html"><font color="#800080">http://cwiki.apache.org/S2WIKI/struts-2-spring-2-jpa-ajax.html</font></a>.</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">Anyway, you may still worry about using one single POJO in every layer; it probably makes the system tightly coupled. But in fact it does not. You have to change the way you regard the &ldquo;domain objects&rdquo;(POJO+Annotation), that move between different layers of the system,carring data, being presented, changed, saved into database, etc. These &ldquo;domain objects&rdquo; are the blood of the system, and can be used by Web Framework, Business Logic code, Persistence API. These &ldquo;domain objects&rdquo; almost only contain data and its getters and setters, or some small logic for conversion of data. They are the only artifacts created, used, changed, transferred by the components in every layers in the system.<o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p></o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">As for JPA, don&rsquo;t worry about it at all, it just absorbs all the essence of Hibernate and uses Annotation instead of hbm.xml. If you are familiar with Hibernate, it will not take you long time to master it.</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">Another issue is DAO layer seems to disappear. Yes, if you use JPA, write another layer of DAO seems to be meaningless. In my point of view, DAO is only useful when you use JDBC or a very big system with multi-layer even in business logic code. If you has already use ORM tool such as Hibernate, JPA, it really doesn&rsquo;t give much benefit for the system, unless it&rsquo;s a very big system.</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-pagination: none; mso-layout-grid-align: none"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'Arial Unicode MS'">I hope this will give you little help.<o:p></o:p></span></p>
          <br/>
          <span style="color:red;">
            <a href="http://fxy1949.javaeye.com/blog/145695#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 03 Dec 2007 20:59:58 +0800</pubDate>
        <link>http://fxy1949.javaeye.com/blog/145695</link>
        <guid>http://fxy1949.javaeye.com/blog/145695</guid>
      </item>
      <item>
        <title>The pattern of invoking EJB3 method from JSF managed bean</title>
        <author>fxy1949</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fxy1949.javaeye.com">fxy1949</a>&nbsp;
          链接：<a href="http://fxy1949.javaeye.com/blog/131691" style="color:red;">http://fxy1949.javaeye.com/blog/131691</a>&nbsp;
          发表时间: 2007年10月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          The following example shows how to invoke a EJB3 session bean from a JSF managed bean.<br /><br />There are some points I need to mention:<br /><br />1) The JNDI name of session bean may vary according to different Application Server and the way you deploy your application.<br />2) Depending your situation,choose the right interface: remote or local.<br />3) Exception handling is up to your own strategy and choice.<br /><br />Last but not least,this is not a complete example,there is something missing.<br /><br /><div class="quote_title">引用</div><div class="quote_div">-----------Web Layer--------------------------------------------------<br /><br />/*<br /> * XXX managed bean<br /> */<br />...<br /><br />public class XXXBean extends MyManagedBean<br />{<br />    // Session bean JNDI name<br />    private static final String EJB_PRODUCT_SESSION= "ProductSession";<br /><br />    // Session bean remote interface<br />    ProductSessionRemote productSession;<br /><br />    // Session bean local interface<br />    //ProductSessionLocal productSession; <br /><br />    public XXXBean<br />    {<br />        try <br />        {<br />            productSession=(ProductSessionRemote)ServiceLocator.getInstance().getEJB(EJB_PRODUCT_SESSION);<br />        }<br />        catch(Exception) {<br />            ...<br />        }<br />        …<br />     }<br /><br />    public String findProduct(…)<br />    {<br />         …<br />         try {<br />             …<br />              product=productSession.findProductById(productId);<br />             …<br />          }<br />         catch(Exception e) <br />         {<br />             processException(e,productId);<br />             return null; // go current page<br />          }<br />         …<br />          return “yyyy”;<br />    }<br /><br />    public String createProduct(…)<br />    {<br />         …<br />         try {<br />             …<br />              product=productSession.createProduct(product);<br />             …<br />          }<br />         catch(Exception e) <br />         {<br />             int ret=processException(e);<br /><br />             // process nivagation according to your exception handling strategy<br />             if ( ret== APPLICATION_EXCEPTION )<br />                return “xxxx”; // go error page<br />             else<br />                …<br />          }<br />         …<br />          return “yyyy”;<br />     }<br />     …<br />}<br /><br /><br />/*<br /> * MyManagedBean, which is extended by all the managed beans.<br /> */<br />...<br /><br />public class MyManaedBean<br />{<br />    …….<br /><br />   /*<br />     * Process exception for invocation session bean<br />     */<br />    protected int processException(Exception e,Object... args)<br />    {<br />        if( e==null )<br />            return -1;<br />        <br />        if (e instanceof AppException) // application exception<br />        {<br />             addMessage(FacesMessage.SEVERITY_ERROR,e.getMessage(),args);<br />             return APPLICATION_EXCEPTION;<br />        }<br />        else<br />        if (e instanceof EJBAccessException) // no permission exception<br />        {<br />             addMessage(FacesMessage.SEVERITY_ERROR,CmmwebKeys.NO_PERMISSION_FAILURE);<br />             return NO_PERMISSION_EXCEPTION;<br />        }<br />        else // exception<br />        {<br />             addMessage(FacesMessage.SEVERITY_ERROR,CmmwebKeys.GENERAL_FAILURE);<br />             return OTHER_EXCEPTION;<br />        }<br />    }<br /><br />    // handle message<br />    protected void addMessage(FacesMessage.Severity severity,String bundleMessageName,Object... args)<br />    {<br />        String message = getBundleMessage(bundleMessageName,args);<br />        FacesContext.getCurrentInstance().addMessage(null,new FacesMessage(severity,message,message));<br />    }<br /><br />    ...<br />}<br /> <br /><br />/*<br /> * ServiceLocator.java<br /> *<br /> * Created on 19 October 2006, 09:45<br /> * @author xfang<br /> *<br /> */<br />...<br /><br />public class ServiceLocator {<br />    <br />    private InitialContext ic;<br />    private Map cache;<br />    <br />    private static ServiceLocator me;<br />    <br />    static {<br />        try {<br />            me = new ServiceLocator();<br />        } catch(NamingException se) {<br />            throw new RuntimeException(se);<br />        }<br />    }<br />    <br />    private ServiceLocator() throws NamingException  {<br />        ic = new InitialContext();<br />        cache = Collections.synchronizedMap(new HashMap());<br />    }<br />    <br />    public static ServiceLocator getInstance() {<br />        return me;<br />    }<br />    <br />    private Object lookup(String jndiName) throws NamingException {<br />        Object cachedObj = cache.get(jndiName);<br />        if (cachedObj == null) {<br />            cachedObj = ic.lookup(jndiName);<br />            cache.put(jndiName, cachedObj);<br />        }<br />        return cachedObj;<br />    }<br />    <br />    /**<br />     * will get the ejb3. If this ejb home factory has already been<br />     * clients need to cast to the type of EJBHome they desire<br />     *<br />     * @return the EJB3 corresponding to the homeName<br />     */<br />    public Object getEJB(String jndiEJBName) throws NamingException {<br />        Object objref = lookup(jndiEJBName);<br />        return objref;<br />    }<br />}<br /><br />-------------EJB Layer------------------------------------------------<br /><br />/*<br /> * Product Session Bean<br /> */<br />...<br /><br />@Stateless<br />@TransactionManagement(value = TransactionManagementType.CONTAINER)<br /><br />public class ProductSession implements ProductSessionLocal,ProductSessionRemote<br />{<br />    @PersistenceContext(unitName="mydb")<br />    private EntityManager em;<br /><br />   /** <br />     * Find a product entity by its ID<br />     */<br />    public Product findProductById(long id) throws AppException,Exception <br />    {<br />	Product product = null;<br /><br />	try <br />         {<br />	    product=(Product)em.find(Product.class,id);  // find from database<br />	<br />             initProduct(product);// initialize lazy-loaded property<br />	} <br />         catch(Exception e) {<br />	    throw e;<br />	}<br /><br />	return product;<br />    }<br /><br />   /** <br />     * create a new product<br />     */<br />    public Product createProduct(Product p) throws AppException,Exception <br />    {<br />	Product product = p;<br /><br />	try {<br /><br />             if ( !validateXXX(product) ) // validate failed!<br />             {<br />                 throw new AppException("AppException.xxx.0001");<br />             }<br />             ...<br />          <br />             em.persist(product); // save to database<br /><br />	    em.refresh(product); // re-initialize entity<br /><br />	    initProduct(product); // initialize lazy-loaded property<br />	} <br />         catch (Exception e) {<br />	    throw e;<br />	}<br /><br />	return product;<br />    }<br />}<br /><br /><br />/*<br /> * Product Session Bean Local interface<br /> */<br />...<br /><br />import javax.ejb.Local;<br /><br />@Local<br />public interface ProductSessionLocal<br />{<br />    Product findProductById(long id) throws AppException,Exception;<br />    Product createProduct(Product product) throws AppException,Exception;<br />}<br /><br />/*<br /> * Product Session Bean Remote interface<br /> */<br />...<br /><br />import javax.ejb.Remote;<br /><br />@Remote<br />public interface ProductSessionRemote<br />{<br />    Product findProductById(long id) throws AppException,Exception;<br />    Product createProduct(Product product) throws AppException,Exception;<br />}<br />------------------------------------------------------------------------</div>
          <br/>
          <span style="color:red;">
            <a href="http://fxy1949.javaeye.com/blog/131691#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 13 Oct 2007 18:07:45 +0800</pubDate>
        <link>http://fxy1949.javaeye.com/blog/131691</link>
        <guid>http://fxy1949.javaeye.com/blog/131691</guid>
      </item>
  </channel>
</rss>