package examples.ejb.sequence.jdbc; import java.io.Serializable; import java.rmi.RemoteException; import java.rmi.Remote; import javax.ejb.*; import java.util.*; import java.sql.*; /** * AutoAccountBean is an EntityBean. This EJBean illustrates: * * * @author Copyright (c) 1998 by WebLogic, Inc. All Rights Reserved. * @author Copyright (c) 1998-1999 by BEA WebXpress. All Rights Reserved. */ public class AutoAccountBean implements EntityBean { final static boolean VERBOSE = true; // ----------------------------------------------------------------- // private variables private transient EntityContext ctx; private transient Properties props; // ----------------------------------------------------------------- // public container managed variables public String accountId; // also the primary Key public double balance; public static int lastKey = 0; public static int maxKey = 0; // ----------------------------------------------------------------- // EntityBean implementation /** * Returns the Primary Key identifying this EJBean. * * @return String Identification */ private String id() { return "" + System.identityHashCode(this) + ", PK = " + (String) ((ctx == null) ? "nullctx" : ((ctx.getPrimaryKey() == null ? "null" : ctx.getPrimaryKey().toString()))); } /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbActivate() { if (VERBOSE) System.out.println("ejbActivate (" + id() + ")"); } /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbPassivate() { if (VERBOSE) System.out.println("ejbPassivate (" + id() + ")"); } /** * Sets the EntityContext for the EJBean. * * @param ctx EntityContext */ public void setEntityContext(EntityContext ctx) { if (VERBOSE) System.out.println("setEntityContext (" + id() + ")"); this.ctx = ctx; props = ctx.getEnvironment(); } /** * Unsets the EntityContext for the EJBean. * */ public void unsetEntityContext() { if (VERBOSE) System.out.println("unsetEntityContext (" + id() + ")"); this.ctx = null; props = null; } /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbLoad() { if (VERBOSE) System.out.println("ejbLoad: (" + id() + ")"); } /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbStore() { if (VERBOSE) System.out.println("ejbStore (" + id() + ")"); } /** * This method is required by the EJB Specification, * but is not used by this example. * * @exception javax.ejb.RemoveException * if the EJBean does not allow removing the EJBean */ public void ejbRemove() throws RemoveException { if (VERBOSE) System.out.println("ejbRemove (" + id() + ")"); } /** * This method corresponds to the create method in the home interface * "AutoAccountHome.java". * The parameter sets of the two methods are identical. When the client calls * AutoAccountHome.create(), the container (which in WebLogic EJB is * also the home) allocates an instance of this EJBean and * calls AutoAccountBean.ejbCreate(). *

* For container-managed persistence, ejbCreate() returns * a void, unlike the case of bean-managed * persistence, where it returns a primary key. * * @param accountID String Account ID * @param initialBalance double Initial Balance * @exception javax.ejb.CreateException * if there is a problem creating the bean */ public void ejbCreate(String accountId, double initialBalance) throws CreateException { if (VERBOSE) System.out.println("AccountBean.ejbCreate( id = " + System.identityHashCode(this) + ", PK = " + accountId + ", " + "initial balance = $ " + initialBalance + ")"); this.accountId = accountId; this.balance = initialBalance; } /** * This method corresponds to the create method in the home interface * "AutoAccountHome.java". * The parameter sets of the two methods are identical. When the client calls * AutoAccountHome.create(), the container (which in WebLogic EJB is * also the home) allocates an instance of this bean and * calls AutoAccountBean.ejbCreate(). *

* For bean-managed persistence, ejbCreate() returns * a primary key, unlike the case of container-managed * persistence, where it returns a void. *

* Unlike the ejbCreate(String accountId, double initialBalance), * this version creates a new AccountID using getNewAccountId(). * * @param initialBalance double Initial Balance * @exception javax.ejb.CreateException * if there is a problem getting an account ID */ public void ejbCreate(double initialBalance) throws CreateException { try { ejbCreate(getNewAccountId(), initialBalance); } catch (Exception e) { throw new CreateException (e.getMessage()); } } /** * This method gets the next account ID. If there are no * more IDs available in the current range, it goes to the * database and retreives a new range of IDs. * The range is set by a parameter in the Deployment Descriptor. * The current range of available IDs is stored in * lastKey and maxKey. * * @return String Next account ID * @exception Exception * if there is a problem getting an account ID */ private String getNewAccountId() throws Exception { if (VERBOSE) System.out.println("getNewAccountId(); lastKey: " + lastKey + " maxKey: " + maxKey); if (lastKey >= maxKey) { // Go to database and set new values for lastKey and maxKey if (VERBOSE) System.out.println("lastKey>=maxKey: getting new range of accountIds"); Connection con = null; Statement stat = null; ResultSet results = null; String idTableName = getIdTableName(); String tableName = getJdbcProperty("tableName"); int range = getRange(); int dbMaxKey; int newMaxKey; try { con = getConnection(); stat = con.createStatement(); int i; stat.executeQuery("select maxKey from " + idTableName + " where tablename = '" + tableName + "'"); results = stat.getResultSet(); if ((results != null) && (results.next())) { dbMaxKey = results.getInt(1); newMaxKey = dbMaxKey + range; i = stat.executeUpdate("update " + idTableName + " set maxKey = " + new Integer(newMaxKey).toString() + " where tablename = '" + tableName + "'"); if (i == 0) { throw new CreateException ("ejbCreate: idTableName (" + idTableName + ") not updated"); } } else { dbMaxKey = maxKey; newMaxKey = maxKey + range; i = stat.executeUpdate("insert into " + idTableName + " (tablename, maxKey) values ('" + tableName + "', " + new Integer(newMaxKey).toString() + ")"); if (i == 0) { throw new CreateException ("ejbCreate: idTableName (" + idTableName + ") not inserted"); } } lastKey = dbMaxKey; maxKey = newMaxKey; } catch (SQLException sqe) { throw new CreateException (sqe.getMessage()); } finally { if (stat != null) try { stat.close();} catch (Exception e) {} if (con != null) try { con.close();} catch (Exception e) {} if (results != null) try { results.close();} catch (Exception e) {} } } return new Integer(++lastKey).toString(); } /** * This method is required by the EJB Specification, * but is not used by this example. * * @param accountID String Account Identification * @param initialBalance double Initial Balance */ public void ejbPostCreate(String accountId, double initialBalance) { if (VERBOSE) System.out.println("ejbPostCreate (" + id() + ")"); } /** * This method is required by the EJB Specification, * but is not used by this example. * * @param initialBalance double Initial Balance */ public void ejbPostCreate(double initialBalance) { if (VERBOSE) System.out.println("ejbPostCreate (" + id() + ")"); } // Application defined methods /** * Adds amount to balance. * * @param amount double Amount * @return double balance */ public double deposit(double amount) { if (VERBOSE) System.out.println("Depositing $" + amount + " into '" + accountId + "'"); balance += amount; return balance; } /** * Subtracts amount from balance. * * @param amount double Amount * @return double Balance * @exception ProcessingErrorException * if Amount > Balance */ public double withdraw(double amount) throws ProcessingErrorException { if (VERBOSE) System.out.println("Withdrawing $" + amount + " from '" + accountId + "'"); if (amount > balance) { throw new ProcessingErrorException("Request to withdraw $" + amount + " more than balance " + balance + " in account " + accountId); } balance -= amount; return balance; } /** * Returns current balance. * * @return double Balance */ public double balance() { return balance; } /** * Returns account ID. * * @return String Account ID */ public String accountId() { return accountId; } /** * Forces static initialization of weblogic.jdbc.jts.Driver * */ static { new weblogic.jdbc.jts.Driver(); // force static initialization } /** * Returns the name of the table used for generating IDs * * @return String Name of table for generating IDs */ private String getIdTableName() { return (String) props.get("idTable"); } /** * Returns the number of unique ids to be allocated each time * * @return int Range of ids */ private int getRange() { return new Integer((String) props.get("creationRange")).intValue(); } /** * Returns value of a property listed in the "jdbc" property of the * "persistentStoreProperties" entry of the deployment descriptor. * * @param propertyName String Name of property to retrieve * @return String Property value */ private String getJdbcProperty(String propertyName) { Hashtable ht; ht = (Hashtable)props.get("persistentStoreProperties"); if (ht != null) { String psType = (String)ht.get("persistentStoreType"); if (psType != null && psType.equalsIgnoreCase("jdbc")) { ht = (Hashtable)ht.get(psType); if (ht != null) return (String)ht.get(propertyName); } } return null; } /** * Returns a connection from the database pool defined in the * deployment descriptor for the bean. * * @return Connection Database connection * if there is an error getting a Connection */ private Connection getConnection() throws SQLException { return DriverManager.getConnection("jdbc:weblogic:jts:" + getJdbcProperty("poolName")); } }