Dashboard > Spring Discuss > Kodo JDO Usage With Spring
  Spring Discuss Log In View a printable version of the current page.  
  Kodo JDO Usage With Spring
Added by Colin Sampaleanu, last edited by Marc Logemann on Jun 09, 2005  (view change)
Labels: 
(None)

The JDO 1.0 API provides no standard mechanism to pass an externally managed connection factory (a DataSource in most cases) to a JDO PersistenceManagerFactory to use.

Spring's LocalPersistenceManagerFactoryBean, which produces a JDO PersistenceManagerFactory, normally uses the standard JDOHelper.getPersistenceManagerFactory() mechanism to get the PMF. The easiest way to feed KODO JDO a Spring managed DataSource is to subclass Spring's LocalPersitenceManagerFactory to instead create the PersistenceManagerFactory as a KODO JDBCPersistenceManagerFactory, which is just a JavaBean which can be configured, and passed a DataSource.

Note that this LocalPersistenceManagerFactoryBean subclass is not included with Spring, since it is Kodo specific, but it is listed here:

package org.springframework.orm.jdo.kodo;

import java.util.Properties;

import javax.jdo.PersistenceManagerFactory;

import kodo.jdbc.conf.JDBCConfigurationImpl;
import kodo.jdbc.runtime.JDBCPersistenceManagerFactory;

/**
 * Kodo specific LocalPersistenceManagerFactoryBean.
 *
 * This exists so we can pass in a Spring-managed connection to the
 * PersistenceManagerFactory. There is no JDO 1.0 standard mechanism
 * to do this.
 */
public class KodoPersistenceManagerFactoryBean
       extends org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean {
    
    Object connectionFactory;
    
    /**
     * Allows a JDO ConnectioFactory to be set (a datasource most of the time)
     * Will be set on the returned PersistenceManagerFactory
     * @param connectionFactory The connectionFactory to set.
     */
    public void setConnectionFactory(Object connectionFactory) {
        this.connectionFactory = connectionFactory;
    }

    /**
     * Override template method from superclass
     */
    protected PersistenceManagerFactory newPersistenceManagerFactory(Properties props) {
        JDBCConfigurationImpl jdoConf = new JDBCConfigurationImpl();
        jdoConf.fromProperties(props);
        if (connectionFactory != null) {
            jdoConf.setConnectionFactory(connectionFactory);
        }
        PersistenceManagerFactory pmf = new JDBCPersistenceManagerFactory(jdoConf);
        return pmf;
    }
}

Now that we have this class, it's simply a matter of configuring it as a normal bean, in the same fashion as the original LocalPersistenceManagerFactoryBean would have been configured. The DataSource itself that we are referring to could have any implementation, i.e. a local DataSource set up via something like Apache DBCP, or alternately a JTA DataSource obtained from JNDI via JndiObjectFactoryBean. There are many Kodo specific and JDO standard properties which may be set, but a sample configuration could look like this:

<bean id="persistenceManagerFactory"
          class="org.springframework.orm.jdo.kodo.KodoPersistenceManagerFactoryBean">
        <property name="connectionFactory">
          <ref bean="dataSource"/>
        </property>
        <property name="jdoProperties">
            <props>
                <prop key="kodo.LicenseKey">xxxx-xxxx-xxxx-xxxx-xxxx</prop>
                <prop key="javax.jdo.PersistenceManagerFactoryClass">kodo.jdbc.runtime.JDBCPersistenceManagerFactory</prop>
                <prop key="javax.jdo.option.Optimistic">true</prop>
                <prop key="javax.jdo.option.RetainValues">true</prop>
                <prop key="javax.jdo.option.NontransactionalRead">true</prop>
                <prop key="javax.jdo.option.NontransactionalWrite">true</prop>

                <prop key="kodo.PersistenceManagerImpl">DetachFields=loaded, DetachOnClose=true</prop>

                <!-- we have FKs pointing to entities with auto-increment PKs -->
                <!-- this needs to be set on config for enhancer too! -->
                <prop key="kodo.jdbc.AutoIncrementConstraints">true</prop>

                <!-- now make sure we don't have to do manual flushes to get queries to see
                     newly added or deleted objects -->
                <prop key="javax.jdo.option.IgnoreCache">false</prop>
                <prop key="kodo.FlushBeforeQueries">true</prop>
                <prop key="kodo.ConnectionRetainMode">transaction</prop>
            </props>
        </property>
    </bean>

The final piece which would be nice to have, but has not been implemented by the original author of this text (Colin Sampaleanu) is a Kodo-specific implementation of Spring's JdoDialect interface. While this is not critical, it would allow the Connection used by JDO to also be pulled out by Spring and attached to the current thread/transaction, so that JDBC could could use it as well. This happens out of the box with Spring's Hibernate implementation, for example.

See Also: Kodo Datasources and ConnectionPools

Site running on a free Atlassian Confluence Open Source Project License granted to Spring Framework. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.5 Build:#811 Jul 25, 2007) - Bug/feature request - Contact Administrators