<document>
  <header>
    <product>resin-ee</product>
    <resin-2.0>$ee/ejb-tut/entity-home.xtp</resin-2.0>
    <title>Entity Bean Home methods (ejbHome)</title>
    <description>
      <p>The EJB 2.0 spec adds home methods to entity beans.  Applications can
        define methods callable from the home interface.  In other words,
        there's no need to create or find an entity bean instance just to
        execute an entity method.  The home methods resemble static Java
        methods or methods in a stateless session bean.</p>
    </description>
  </header>

  <body>
    <summary/>
<section title="EJB Implementation">

<p>This example adds a <var/hello()/> method and an <var/add/> method
to the home interface.  In this example, there are no entity bean
instances.  All the work is done by the home interface.  The home
methods are implemented in the bean by adding <var/ejbHome/> to the
name.  So <var/hello/> will become <var/ejbHomeHello/>.</p>

<p>In essence, the home interface lets you create a simple service,
like the <a href="protocols|tutorial/burlap-add/index">Burlap hello</a> service, and
stick to the EJB API.</p>

<p>Even though there are no entity bean instances, the
<var/findByPrimaryKey/> method is still needed.</p>

<example title="Home.java">
package test;

import java.rmi.*;

public interface Home extends javax.ejb.EJBHome {
  public String hello() throws RemoteException;

  public int add(int a, int b) throws RemoteException;

  public HomeObj findByPrimaryKey(String a)
    throws RemoteException, FinderException;
}
</example>

<p>The object interface is empty.  Since the EJB spec requires it,
we still need to define HelloObj.</p>

<example title="HelloObj.java">
package test;

public interface HelloObj extends javax.ejb.EJBObject {
}
</example>

<p>As usual, the work is done the HelloBean.  The home methods all
start with <var/ejbHome/>.  <var/ejbHomeHello/> implements the
<var/hello/> method.  <var/ejbHome/add/> implements the add method.</p>

<p><var/ejbFindByPrimaryKey/> is required, but it's easy to create a
stub implementation that just returns an exception.</p>

<example title="HelloBean.java">
package test;

import javax.ejb.*;

public class HelloBean extends com.caucho.ejb.AbstractEntityBean {
  public String ejbHomeHello()
  {
    return "Hello, world";
  }

  public int ejbHomeAdd(int a, int b)
  {
    return a + b;
  }

  public String ejbFindByPrimaryKey(String key)
    throws FinderException
  {
    throw new FinderException("no children");
  }
}
</example>

</section>

<section title="Servlet Implementation">

<p>The client in this example is a servlet.  As with other EJBs,
the client gets the home interface using JNDI.  Since it's only
necessary to do the JNDI lookup once, the servlet caches the home
object as a servlet variable.</p>

<example>
package test.entity.home;

import java.io.*;

import javax.servlet.*;
import javax.servlet.http.*;

import javax.ejb.*;
import javax.naming.*;

public class HomeServlet extends GenericServlet {
  Home home;

  public void init()
    throws ServletException
  {
    try {
      Context env = (Context) new InitialContext().lookup("java:comp/env");
      home = (Home) env.lookup("ejb/home");
    } catch (Exception e) {
      throw new ServletException(e);
    }
  }

  public void service(ServletRequest req, ServletResponse res)
    throws IOException, ServletException
  {
    PrintWriter pw = res.getWriter();
    
    try {
      pw.println("message: " + home.hello() + "<br>");
      
      pw.println("1 + 3 = " + home.add(1, 3) + "<br>");
      pw.println("7 + 1 = " + home.add(7, 1) + "<br>");
    } catch (Exception e) {
      throw new ServletException(e);
    }
  }
}
</example>

</section>

<section title="Burlap protocol for the example">

<p>The Burlap calls for home methods are particularly simple.  Since
there's no object, the client can call the home method directly.  The
protocol is identical to the <a href="protocols|tutorial/burlap-add/index">Burlap
hello</a> example, so clients can work with either unchanged.</p>

<p>Since the example uses the burlap protocol, you can use 'telnet' as a
simple client.</p>

<section title="hello() call">

<results>
unix> <var/telnet localhost 8080/>
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.
<var/POST /servlet/test.entity.home.HomeServlet HTTP/1.0/>
<var/Content-Length: 54/>

<var/&lt;burlap:call>/>
<var/&lt;method>hello&lt;/method>/>
<var/&lt;/burlap:call>/>

HTTP/1.0 200 OK
Server: Resin/1.3.s010312
Content-Length: 73
Date: Tue, 13 Mar 2001 03:15:27 GMT

&lt;burlap:reply>
&lt;value>
&lt;string>Hello, world&lt;/string>
&lt;/value>
&lt;/burlap:reply>
</results>

<p>The results have some added whitespace to make the example more
readable.  The server doesn't bother trying to pretty-print the results.

</section>

<section title="add(2, 3) call">

<p>The add call has two integer arguments.  The integers directly
follow the method.

<p>The example below uses the short method name, <var/add/>.  To
support method overloading, the Burlap server also accepts the method
name <var/add_int_int/>.</p>

<results>
unix> <var/telnet localhost 8080/>
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.
<var/POST /ejb/home HTTP/1.0/>
<var/Content-Length: 77/>

<var/&lt;burlap:call>/>
<var/&lt;method>add&lt;/method>/>
<var/&lt;int>2&lt;/int>/>
<var/&lt;int>3&lt;/int>/>
<var/&lt;/burlap:call>/>

HTTP/1.0 200 OK
Server: Resin/1.3.s010404
Content-Length: 56
Date: Thu, 05 Apr 2001 05:36:42 GMT

&lt;burlap:reply>
&lt;value>
&lt;int>5&lt;/int>
&lt;/value>
&lt;/burlap:reply>
</results>

</section>

<section title="metadata call">

<p>The Java client, in this case HomeServlet, needs to know 
the Home interface in order to generate stub for the Burlap protocol.
Since the client doesn't know that information, it needs to ask the
server for the classname.  Burlap handles that with a reserved
metadata call <var/_burlap_getAttribute/>.</p>

<results>
unix> <var/telnet localhost 8080/>
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.
<var/POST /ejb/home HTTP/1.0/>
<var/Content-Length: 95/>

<var/&lt;burlap:call>/>
<var/&lt;method>_burlap_getAttribute&lt;/method>/>
<var/&lt;string>home-class&lt;/string>/>
<var/&lt;/burlap:call>/>

HTTP/1.0 200 OK
Server: Resin/1.3.s010404
Content-Length: 82
Date: Thu, 05 Apr 2001 05:39:23 GMT

&lt;burlap:reply>
&lt;value>
&lt;string>test.entity.home.Home&lt;/string>
&lt;/value>
&lt;/burlap:reply>
</results>

</section>
</section>
  </body>
</document>
