13.2 JDO and Servlets


Applications with a Web-based presentation layer can use JDO in at least two different ways:

  • Integration of JDO with an EJB service-oriented architecture and Data Transfer (Value) objects was discussed in depth in an earlier chapter. Such an approach could use a Web UI without JDO access from the presentation layer.

  • In another architecture, the JDO API could be used directly in the Servlet layer, including JSP pages as views. This approach is discussed briefly here.

The second architecture is straightforward: The business logic is in plain old Java objects (POJO) co-located to the presentation tier . The business logic and the presentation layer (Servlets and JSP) can use the JDO API directly.

In a Model-View-Controller (MVC) architecture as often used in today's Web-based applications, two variations are possible with JDO:

  • In a Push MVC model, the UI Controller (e.g., a Struts Action) would access the JDO API and then "push" certain persistent objects for display to a View. Technically, the objects are usually forwarded along as attributes stored into the request. The View would usually be implemented as a JSP or, alternatively, some template engine. The View in this variation only uses something like the useBean JSP tag; it does not access the JDO API directly.

  • In a Pull MVC model, the Controller could forward to a View that does use the JDO API. For example, a JSP-based View could use JDO to execute and iterate through a Query , possibly prepared by a controller. Such functionality can be prepackaged into convenient JSP tag libraries.

Some of the questions that can arise in using the JDO and Servlet API together (with both MVC approaches), which are briefly addressed in the next few paragraphs, include the following:

  • Should optimistic or datastore transactions be used?

  • What about non-transactional reads?

  • How is the PersistenceManagerFactory initialized and found? Where should the PersistenceManager be stored? Session, request, or thread-local ?

  • Can persistent objects be stored in the Servlet session?

Regarding the two different transaction types and other transaction configurations that JDO supports, one particular combination is often used and makes sense in the type of Web applications described here: Using optimistic transactions for write access and a PersistenceManager with non-transactional read for read-only access for display. This configuration allows a JDO implementation to optimally leverage the PersistenceManagerFactory (PMF) global in-memory cache and generally leads to good performance and scalability. For example, the MVC Actions can start and commit transactions, while the Views (in an MVC Pull model) can use non-transactional reads.

The PersistenceManagerFactory can be initialized and looked up in two ways in Servlet applications: Either an application (or proprietary framework) specific "helper" class creates, configures and holds onto the PMF. This allows Servlets to use this helper class to obtain a new PersistenceManager when required. Or, alternatively, a Servlet application could also leverage JDO's J2EE integration and obtain a new PersistenceManager from a PMF bound into JNDI by the respective JCA adapter. This allows Servlet applications to use a shared transaction across JDO, JDBC, JMS, and so on, as described in Chapter 11. Of course, all this is no different from what has been described earlier in this book, the classical managed and unmanaged JDO scenarios.

After a PersistenceManager is obtained, there are two possible architectures:

  • Storing as attribute in the request context: A Servlet filter, a Struts request processor, or any similar mechanism obtains a new PersistenceManager when the processing of a request starts. Then the Controller and possibly View work with it. At the end of the request, the PersistenceManager is closed. Particular care needs to be taken that the PM is always closed and transactions rolled back even if an exception occurs rendering the view. This architecture can lead to great scalability. [8]

    [8] The PersistenceManager could also be closed at the end of the controller already, before forwarding to a View, in a pure "Push MVC" model. However, with this approach a lot of issues similar to the ones raised in the EJB chapter arise, around having to make instances transient, using pm.retrieve() , and so on. The advantage of such an architecture particularly when using optimistic JDO transactions are dubious, and it is generally not recommended.

  • Storing in the session: An HttpSessionListener (or some Controller explicitly) could obtain a new PersistenceManager and store it in the Session for the lifetime of the session.

The second approach can appear to make application development somewhat easier. In this case, persistent objects (e.g., Query results) can be directly stored into the session as well, see below. However, because a PersistenceManager is not serializable (only a PersistenceManagerFactory is) this architecture actually prevents "distributable" Web applications for load-balancing and fail-over on clusters. It is recommended only for relatively simple applications with no need for session passivation and replication.

A related issue is the one of storing persistent objects as attributes into the session, if the PersistenceManager is in the session. Again, persistent objects are not generally serializable for session replication; see the respective discussion in Chapter 9.

It is generally preferable and possible to store only identities of persistent objects into the session using PersistenceManager.getObjectId() and then retrieve the object in the next request via PersistenceManager.getObjectById() . This is conceptually similar to what was discussed in Chapter 5 for stateful session beans.

Alternatively, a similar but completely stateless architecture can be used if JDO identities are passed only via URL and hidden HTML FORM INPUT fields. In this scenario, the JDO identity is converted to and from String via PersistenceManager.getObjectId().toString() and PersistenceManager.NewObjectIdInstance() .

It is worth noting that obtaining a PersistenceManager for each request and looking up objects via identities (as opposed to storing the PersistenceManager and persistent objects in the session) does not necessarily lead to less performance. A good JDO implementation reuses instances and ideally does not require underlying datastore access because of caching when looking up objects via a stored identity.



Core Java Data Objects
Core Java Data Objects
ISBN: 0131407317
EAN: 2147483647
Year: 2003
Pages: 146

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