Optimizing Entity Bean Persistence

   

Building a Pick List

A common requirement for a business application is to display a list of items from which a user makes a selection. This can be a list of customers or products in a catalog or anything else. The basic behavior is the same ”the user views a list that contains some summary attributes for each entry and then picks from the list. The system responds by displaying a more detailed view of the selection that includes additional attributes.

The potential performance problem with building a pick list is that reading all the attributes for the items in the list is inefficient. It would be faster to only read the summary information that's needed for the list and then read the detailed attributes for an entry only when they're requested . If you're using entity beans for all your data retrieval from the database, this can create a problem. For example, the findAllAuctions finder method declared in Chapter 5 as part of the EnglishAuctionHome interface could be executed by a session bean method to build a list of auctions for the user to view. If you think back to how a finder method works, you know that simply executing a finder doesn't instantiate any entity objects. All an ejbFind method has to do is determine the primary key values that match the selection criteria and return those. It's not until a business method is executed on the component interface corresponding to a particular object identity that an entity object has to be loaded and activated. The point here is that a finder method approach might be acceptable if you can avoid business method calls on the entities that aren't needed for display. Suppose you have 1,000 auctions in the database but only 15 at a time need to be returned to the Web tier for display to the user. Using a finder method might be an acceptable approach if the finder method query can be built to only return the 15 auctions that are needed. Or if the filtering done by the application doesn't involve any processing (sorting, for example) that causes a business method call to each entity. This latter case always has some additional overhead because 1,000 primary keys would have to be read and returned even if the entities associated with the majority of them were never loaded.

If the overhead of loading and instantiating unneeded primary keys within a finder is too much or the logic that determines which elements go in a list requires attributes other than the primary key, you should consider another option. Instead of executing a finder method, you can implement a session bean method that accesses the database directly using JDBC (or an ORM framework query) and loads the attributes needed to build the pick list. In this case, the session bean method can execute whatever query is necessary to build the view objects used by the Web tier. When the user requests the details for an entry displayed in the list, the primary key associated with that particular view object can be used to make a findByPrimaryKey call that loads the corresponding entity object.

Listing 17.4 shows a method that could be added to the implementation of the AuctionHouseBean session bean to retrieve the data needed to build a pick list of auctions.

Listing 17.4 getAllAuctions “A Method for Building a List of Views in a Session Bean/**
 * Return entries for an auction pick list. The session bean performs   * the necessary queries instead of accessing an entity bean finder method   * in this case.   *   * @param startIndex the element to start with (1-based)   * @param numToReturn the number of auction views to return   * @return a list of AuctionSummaryView objects sorted by name   */  public List getAllAuctions(int startIndex, int numToReturn) {   Connection con = null;    PreparedStatement stmt = null;    ResultSet rs = null;    List auctions = new ArrayList();    try {     con = BMPHelper.getConnection("auctionSource");      // perform a query to select all the necessary attributes      stmt = con.prepareStatement("SELECT id, Name, Status, LeadingBidId, " +        "ScheduledEndDate FROM auction ORDER BY Name");      rs = stmt.executeQuery();      // move to the right spot in the result set      for (int i=0; i<startIndex; i++) {       if (!rs.next()) {         // not enough entries, return an empty list          return auctions;        }      }      // create views for the desired number of auctions      PreparedStatement bidStmt = con.prepareStatement(       "SELECT Amount FROM bid where id = ?");      for (int i=0; i<numToReturn; i++) {       if (rs.next()) {         // instantiate a view and set its attributes          AuctionSummaryView view = new AuctionSummaryView();          view.setId((Integer)rs.getObject("id"));          view.setName(rs.getString("Name"));          view.setStatus(rs.getString("Status"));          view.setScheduledEndDateTime(rs.getTimestamp("ScheduledEndDate"));          Integer leadingBidId = (Integer)rs.getObject("LeadingBidId");          view.setLeadingBidAmount(null);          if (leadingBidId != null ) {           // load the leading bid to get the bid amount            bidStmt.setInt(1, leadingBidId.intValue());            ResultSet rsBid = bidStmt.executeQuery();            if (rsBid.next()) {             BigDecimal bd = rsBid.getBigDecimal("Amount");              view.setLeadingBidAmount(new Double(bd.doubleValue()));            }          }          // add the view to the list to return          auctions.add(view);        }        else {         break;        }      }      bidStmt.close();    }    catch (SQLException e) {     // throw a system exception if a database access error occurs      throw new EJBException(e);    }    finally {     // close the connection      BMPHelper.cleanup(stmt, con);    }    // return the views    return auctions;  } 

What's important about the concept illustrated by Listing 17.4 is that choosing entity beans to manage your persistent data doesn't rule out using more efficient access in certain cases. This is especially true when you need read-only access to your entity data. Unless you're dealing with entities that only result in a small number of instances, you should always consider using a session bean to build your lists of summary data. Entity beans provide very helpful functionality when you need to create and edit persistent data, but the associated overhead can quickly get in the way when all you need to do is read and report some information.



Special Edition Using Enterprise JavaBeans 2.0
Special Edition Using Enterprise JavaBeans 2.0
ISBN: 0789725673
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net