Hi Craig,

This proposal reminds me the proxy EntityManagers that a Java EE 5 container 
can use, which mean that my post yesterday regarding automatic injection of 
JEntityManager was probably too naive. Maybe the new proxy PersistenceManager 
can also help somehow in injection of a PersistenceManager in a Java EE 5 
container? Also, it might make sense to implement such a proxy (or most of its 
activity) on the JDO side rather than by every implementation (I guess that at 
least other vendors may agree with that). Therefore the right location for a 
new method might be in JDOHelper.

Regards,

Ilan

  ----- Original Message ----- 
  From: Craig L Russell 
  To: Apache JDO project ; JDO Expert Group 
  Sent: Monday, October 09, 2006 7:58 PM
  Subject: Proposal for new method (long)


  Javadogs, 


  I'd like to propose a solution to a problem that we have with usability in 
the web tier. When using a servlet, each method that needs access to a 
PersistenceManager needs to figure out where the current PersistenceManager is, 
and if it is even active. There are many ways around this issue, but they are 
not general. Among the workarounds are putting the active PersistenceManager 
into the servlet context as a request or session attribute, passing the 
PersistenceManager explicitly as a parameter, and putting the 
PersistenceManager into a ThreadLocal field. 


  Of these workarounds, the one with the most appeal is the ThreadLocal 
solution. So I'd like to propose that we formalize this by adding a method to 
return a thread-safe PersistenceManager proxy associated with a 
PersistenceManagerFactory that can be implemented as a singleton, stored in a 
component's static field, and that dynamically binds to the PersistenceManager 
that is currently active on the thread.


  Multiple PersistenceManager proxies can be active, each with its own binding 
to a (possibly different) PersistenceManagerFactory.


  The benefit of this proposal is ease of use for web and ejb components that 
currently have to manage their own PersistenceManager resources. Instead of 
having to look up and store a PersistenceManager in each method of each 
component that needs one, looking up the PersistenceManagerFactory can be done 
once during initialization of the component.


  The limitations of the proposal is that in environments that do not support 
Java EE 5 TransactionSynchronizationRegistry (i.e. J2SE servers and Java SE), 
only one PersistenceManager per PersistenceManagerFactory can be used per 
thread (which maps to a single web request), and only one transaction can be 
used per PersistenceManager.


  In environments that support Java EE 5 TransactionSynchronizationRegistry, 
container-managed transactions can be used, including the ability to suspend 
transactions. 


  If used in an environment that does not support Java EE 5 
TransactionSynchronizationRegistry, the behavior is as follows:


  The first component to use a PersistenceManager method on a thread would get 
a PersistenceManager from the factory. Subsequent callers would use the same 
PersistenceManager delegate until the transaction completed, at which time the 
PersistenceManager is cleared and the first subsequent request would create a 
new one.


  Implementation: The proxy would delegate most methods to the current 
PersistenceManager, as determined by the ThreadLocal field being non-null. 
Calling close() would have no effect. If the ThreadLocal field is null, then 
getPersistenceManager() would be called on the PersistenceManagerFactory. A 
synchronization instance would be created and registered with the 
currentTransaction of the newly acquired PersistenceManager, the 
PersistenceManager would be set into the ThreadLocal, and then the request wold 
be delegated to the new PersistenceManager. At afterCompletion, the ThreadLocal 
would be nullified.


  If used in an environment that supports Java EE 5 
TransactionSynchronizationRegistry, the behavior is as follows:


  The first component to use a PersistenceManager method in a managed 
transaction would get a PersistenceManager from the factory. Subsequent callers 
in the same transaction would use the same PersistenceManager delegate until 
the transaction completed, at which time the PersistenceManager is cleared and 
the first request in a new transaction would create a new one.


  Implementation: The proxy would delegate most methods to the current 
PersistenceManager, as determined by the TransactionSynchronizationRegistry 
entry for the PersistenceManagerFactory being non-null. Calling close() would 
have no effect. If the TransactionSynchronizationRegistry entry for the 
PersistenceManagerFactory is null, then getPersistenceManager() would be called 
on the PersistenceManagerFactory. An interposed synchronization instance would 
be created and registered with the TransactionSynchronizationRegistry, the 
PersistenceManager would be set into the TransactionSynchronizationRegistry 
entry for the PersistenceManagerFactory, and then the request wold be delegated 
to the new PersistenceManager. At afterCompletion, the 
TransactionSynchronizationRegistry entry for the PersistenceManagerFactory 
would be nullified.


  If we agree on the semantics of this behavior, the method can be implemented 
as a helper method of JDOHelper, PersistenceManager getPersistenceManagerProxy 
or something like it (suggestions welcome).


  To support container-managed transactions in J2EE servers (1.4 and earlier), 
we would have to put the method on PersistenceManagerFactory and allow the 
implementation to use its own secret sauce to provide the proper semantics. If 
the jdo implementation chose, it could simply delegate to the JDOHelper version 
of the method, with the limitations therein.


  Craig


  Craig Russell

  Architect, Sun Java Enterprise System http://java.sun.com/products/jdo

  408 276-5638 mailto:[EMAIL PROTECTED]

  P.S. A good JDO? O, Gasp!


Reply via email to