<?xml version="1.0" encoding="UTF-8"?>

<section version="5.0" 
         xmlns="http://docbook.org/ns/docbook" 
         xmlns:xlink="http://www.w3.org/1999/xlink" 
         xmlns:xi="http://www.w3.org/2001/XInclude" 
         xmlns:svg="http://www.w3.org/2000/svg" 
         xmlns:mml="http://www.w3.org/1998/Math/MathML" 
         xmlns:html="http://www.w3.org/1999/xhtml" 
         xmlns:db="http://docbook.org/ns/docbook" 
         xml:lang="en" 
         xml:id="ejb2.bmp">
  <info><title>Writing Database Access Methods for Bean Managed Persistence</title></info>
  <para>
     For 
    bean-managed persistence
    , data access operations are developed by the bean provider using the JDBC interface. However, getting database connections must be obtained through the 
    javax.sql.DataSource
     interface on a datasource object provided by the EJB platform. This is mandatory since the EJB platform is responsible for managing the connection pool and for transaction management. Thus, to get a JDBC connection, in each method performing database operations, the bean provider must: 
  </para>
  <itemizedlist>
    <listitem><para>
        call the 
        getConnection(...)
         method of the DataSource object, to     obtain a connection to perform the JDBC operations in the current     transactional context (if there are JDBC operations),
    </para></listitem>
    <listitem><para>
        call the 
        close()
         method on this connection after the database     access operations, so that the connection can be returned to the     connection pool (and be dissociated from the potential current     transaction).
    </para></listitem>
  </itemizedlist>
  <para>
     A method that performs database access must always contain the getConnection and close statements, as follows: 
  </para>
  <screen>
public void doSomethingInDB (...) {
  conn = dataSource.getConnection();
  ... // Database access operations
  conn.close();
}</screen>
  <para>
     A DataSource object associates a JDBC driver with a database (as an ODBC datasource). It is created and registered in JNDI by the EJB server at launch time (refer also to the section "
    <link xlink:href="configuration_guide.html#config.jdbc">
      JDBC DataSources configuration
    </link>
    ").  
  </para>
  <para>
      A DataSource object is a resource manager connection factory for 
      <literal>
        java.sql.Connection
      </literal>
       objects, which implements connections to a database management system. The enterprise bean code refers to resource factories using logical names called "Resource manager connection factory references." The resource manager connection factory references are special entries in the enterprise bean environment. The bean provider must use resource manager connection factory references to obtain the datasource object as follow:
  </para>
  <itemizedlist>
    <listitem><para>
        Declare the resource reference in the standard deployment descriptor     using a 
        <literal>
          resource-ref
        </literal>
         element.
    </para></listitem>
    <listitem><para>
        Lookup the datasource in the enterprise bean environment using the JNDI interface (refer to the section
        <link xlink:href="ejb2_programmer_guide.html#ejb2.environment">
          Enterprise Bean's Environment
        </link>
        ).
    </para></listitem>
  </itemizedlist>
  <para>
     The deployer binds the resource manager connection factory references to the actual resource factories that are configured in the server. This binding is done in the JOnAS-specific deployment descriptor using the jonas-resource element.
  </para> 
  <section xml:id="ejb2.bmp.example">
    <info><title>Example</title></info>
    <para>
       The declaration of the resource reference in the standard deployment descriptor looks like the following: 
    </para>
    <screen>
&lt;resource-ref&gt;
&lt;res-ref-name&gt;jdbc/AccountExplDs&lt;/res-ref-name&gt;
&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&lt;/resource-ref&gt;</screen>
    <para>
       The &lt;res-auth&gt; element indicates which of the two resource manager authentication approaches is used:
    </para>
    <itemizedlist>
      <listitem><para>
          Container
          : the deployer sets up the sign-on information.
      </para></listitem>
      <listitem><para>
          Bean
          : the bean programmer should use the getConnection method     with user and password parameters.
      </para></listitem>
    </itemizedlist>
    <para>
       The JOnAS-specific deployment descriptor must map the environment JNDI name of the resource to the actual JNDI name of the resource object managed by the EJB server. This is done in the &lt;jonas-resource&gt; element. 
    </para>
    <screen>
 &lt;jonas-entity&gt;
  &lt;ejb-name&gt;AccountExpl&lt;/ejb-name&gt;
  &lt;jndi-name&gt;AccountExplHome&lt;/jndi-name&gt;
  &lt;jonas-resource&gt;
  &lt;res-ref-name&gt;jdbc/AccountExplDs&lt;/res-ref-name&gt;
  &lt;jndi-name&gt;jdbc_1&lt;/jndi-name&gt;
  &lt;/jonas-resource&gt;
  &lt;/jonas-entity&gt;</screen>
    <para>
       The ejbStore method of the same Account example with bean-managed persistence is shown in the following example. It performs JDBC operations to update the database record representing the state of the entity bean instance. The JDBC connection is obtained from the datasource associated with the bean. This datasource has been instantiated by the EJB server and is available for the bean through its resource reference name, which is defined in the standard deployment descriptor.
    </para>  
    <para>
        In the bean, a reference to a datasource object of the EJB server is initialized:
    </para>
    <para>
        <literal>
          it = new InitialContext();
        </literal>
    </para>
    <para>
        <literal>
          ds = (DataSource)it.lookup("java:comp/env/jdbc/AccountExplDs");
        </literal>
    </para>
    <para>
        Then, this datasource object is used in the implementation of the methods performing JDBC operations, such as ejbStore, as illustrated in the following:
    </para>
    <screen>
public void ejbStore
 Connection conn = null;
  PreparedStatement stmt = null;
  try { // get a connection
  conn = ds.getConnection();
  // store Object state in DB
  stmt = conn.prepareStatement("update account set customer=?,balance=? where accno=?");
  stmt.setString(1, customer);
  stmt.setDouble(2, balance);
  Integer pk = (Integer)entityContext.getPrimaryKey();
  stmt.setInt(3, pk.accno);
  stmt.executeUpdate();
  } catch (SQLException e) {
  throw new javax.ejb.EJBException("Failed to store bean to database", e);
  } finally {
  try {
  if (stmt != null) stmt.close();  // close statement
  if (conn != null) conn.close();  // release connection
  } catch (Exception ignore) {}
  }
}   </screen>
    <para>
       Note that the close statement instruction may be important if the server is intensively accessed by many clients performing entity bean access. If the statement is not closed in the finally block, since 
      stmt
       is in the scope of the method, it will be deleted at the end of the method (and the close will be implicitly done). However, it may be some time before the Java garbage collector deletes the statement object. Therefore, if the number of clients performing entity bean access is important, the DBMS may raise a "too many opened cursors" exception (a JDBC statement corresponds to a DBMS cursor). Since connection pooling is performed by the platform, closing the connection will not result in a physical connection close, therefore opened cursors will not be closed. Thus, it is preferable to explicitly close the statement in the method.
    </para> 
    <para>
        It is a good programming practice to put the JDBC connection and JDBC statement close operations in a finally bloc of the try statement.
    </para>
  </section>
</section>