I really like the “help” that Spring gives to the tools that you use every day. Some of the items are small things, some are larger, but they all take off some of the burden of development.
I really like the *Template code (Jdbc, Jdo, Hibernate, etc) that wraps the data tier. Today I really liked seeing the hard work that Juergen put into the JdoTemplate/subsystems.
I have projects using Spring/JDO, so thanks to Juergen’s efforts, he has helped make them a success.
I’ve significantly refined Spring’s JDO support, to get it closer to the level of our Hibernate support:
* Standard JDOException -> DataAccessException conversion in PersistenceManagerFactoryUtils is more sophisticated now, properly detecting JDOObjectNotFoundException, JDOOptimisticVerificationException and JDODataStoreException. For more sophisticated, implementation-specific exception translation (for example, detecing data integrity violation), there’s still the need to implement JdoDialect’s “translateException” method.
* JdoDialect has a “beginTransaction” method now, passing in a Spring TransactionDefinition. Implementations can apply the isolation level and/or transaction timeout before they call javax.jdo.Transaction’s “begin”. Spring’s JdoTransactionManager delegates to this method; DefaultJdoDialect does nothing special here, but custom JdoDialect implementations can override this. (Note that both HibernateTransactionManager and DataSourceTransactionManager support isolation levels and timeouts.)
* JdoDialect has a “releaseJdbcConnection” method now, for JDO implementations that expect the JDBC Connection handle that they returned on “getJdbcConnection” to be explictly released. (If explicit closing is not necessary, this method can be empty.) Spring’s JdoTransactionManager properly invokes “releaseJdbcConnection” on transaction cleanup. Note that “getJdbcConnection” returns a ConnectionHandle, to be passed into “releaseJdbcConnection”, which allows for a wider range of release strategies.
* JdoTemplate features a number of convenience methods now, for typical data access operations (load, save, delete, find). Those methods are defined in the new JdoOperations interface; this is analagous to HibernateTemplate and HibernateOperations. The names of the methods follow JDO naming conventions, to look natural to people that are used to the PersistenceManager API (and to imply the same semantics). For more sophisticated querying needs, you still need to implement a JdoCallback and work with the JDO Query API.
* The jdo.support package provides OpenPersistenceManagerInViewInterceptor (for Spring’s web MVC framework) and OpenPersistenceManagerInViewFilter (Servlet 2.3 Filter) implementations now, for keeping a PersistenceManager open during the entire request processing. Spring-managed transactions will simply work on that thread-bound PersistenceManager. This is particularly useful for JDO, as the PersistenceManager will always be in a consistent state, even if exceptions got thrown (in contrast to Hibernate).
All of this should work with any (relational) JDO 1.0 implementation. Please review those refinements and tell me about any gaps or inconsistencies!