Dashboard > HOW-TOS > Home > Spring, OJB, and Struts Third Installment. JNDI and Caching
HOW-TOS Log In   View a printable version of the current page.
Spring, OJB, and Struts Third Installment. JNDI and Caching
Added by Jason McKerr, last edited by K Lars Lohn on Jul 26, 2005  (view change)
Labels: 
(None)

Part 1 Part 2 Part 3

OK, this is the third and final installment of using Spring and Object/RelationalBridge (OJB) together. Previous installments can be found at the following:

As with the last two installments, I have a complete sample application. However, I'm no longer using HSQLDB for the database engine. You will have to have your own. I am using MySQL. For Tomcat and MySQL users, follow the following installation steps:

  1. Download it from here: myusersVersion3.war
  2. Unzip into your webapps directory and REMOVE THE WAR FROM THE WEBAPPS DIRECTORY
  3. Move the included myusers.xml config file to your <tomcat-root>/conf/Catalina/localhost directory. This file sets up the JNDI-based datasource for the application server and the MyUsers application. You need to edit the following properties in this file
    1. driverClassName (if other than MySQL)
    2. url
    3. username
    4. password
  4. Download the MySQL drivers, and stick in <tomcat-root>/common/lib
  5. In your MySQL database create a database called appfuse and a user with appropriate names matching those in step 3.
  6. In the application's myusers/db directory there is a DDL script called mysql.sql. Run that to create the table appropriately. Please note, I made the first_name field unique so that I could run a rollback test. Explained later.
  7. Start Tomcat by going to <tomcat-root>/bin and running catalin.sh run or catalina.bat run.
  8. With a browser go to *http://localhost:8080/myusers*

This installment is just cleaning up some final details. Two things really:

  • Using JNDI-type datasources with your application server (Tomcat in this case)
  • User other OJB caching strategies.

So I'm not actually doing any further real development to the object model. This is just docs for setting up Spring/OJB in non-localized fashion. Easy stuff really.

  • To switch to JNDI Lookups and different caching strategy you have NUMBER steps to complete:
    1) Edit your applicationContext.xml so that all you have are your application specific beans.
    • First thing to do is remove any connection information contained in your applicationContext.xml file. You do not need a JNDI dataSource in this file when using OJB.
    • Remove the bean definition for the local OJB configurer (org.springframework.orm.ojb.support.LocalOjbConfigurer).
    • Here's my applicationContext.xml:
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
          "http://www.springframework.org/dtd/spring-beans.dtd">
      
      <beans>
        <!-- Transaction manager for a single OJB PersistenceBroker (alternative to JTA) -->
        <bean id="transactionManager"
         class="org.springframework.orm.ojb.PersistenceBrokerTransactionManager"/>
      	
        <bean id="userDAO" class="org.appfuse.dao.UserDAOOjbImpl"/>
      	
        <bean id="userManagerTarget" class="org.appfuse.dao.UserDAOImpl">
          <property name="userDAO">
            <ref local="userDAO"/>
          </property>
        </bean>
      	
        <bean id="userManager"
         class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          <property name="transactionManager">
            <ref local="transactionManager"/>
          </property>
          <property name="target">
            <ref local="userManagerTarget"/>
          </property>
          <property name="transactionAttributes">
            <props>
              <prop key="save*">PROPAGATION_REQUIRED</prop>
              <prop key="remove*">PROPAGATION_REQUIRED</prop>
              <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>
          </property>
        </bean>
      </beans>

      2) Change your OJB.properties file: In the previous two samples, we used Spring's local connection system for database connections. We want to switch back to one of the OJB strategies so that database strategies like caching are now independent of Spring (I'll get to that in a minute). Anyway, we were using

      ConnectionFactoryClass=org.springframework.orm.ojb.support.LocalDataSourceConnectionFactory

      I've changed that to:

      ConnectionFactoryClass=org.apache.ojb.broker.accesslayer.ConnectionFactoryPooledImpl

      3) Edit your repository.xml file (OJB-repository.xml in this case).

      • Add JNDI information to your jdbc-connection-descriptor.
      • Caching: Now that our datasources are independent of Spring, we no longer have to use the PerBroker caching strategy (See Juergen Hoeller's email for more info).
      • This is what our OJB-repository.xml file now looks like.
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE descriptor-repository PUBLIC 
        "-//Apache Software Foundation//DTD OJB Repository//EN" "repository.dtd">
        
          <descriptor-repository version="1.0" isolation-level="read-uncommitted">
            <jdbc-connection-descriptor 
             jcd-alias="dataSource" 
             default-connection="true" 
             platform="MySQL" 
             jdbc-level="3.0" 
             useAutoCommit="1"
             eager-release="false"
             batch-mode="false"
             jndi-datasource-name="java:comp/env/jdbc/appFuse"
             ignoreAutoCommitExceptions="false">
        		
            <object-cache class="org.apache.ojb.broker.cache.ObjectCacheDefaultImpl">
              <attribute attribute-name="cacheExcludes" attribute-value=""/>
              <attribute attribute-name="timeout" attribute-value="900"/>
              <attribute attribute-name="autoSync" attribute-value="true"/>
              <attribute attribute-name="cachingKeyType" attribute-value="0"/>
              <attribute attribute-name="useSoftReferences" attribute-value="true"/>
            </object-cache>
        		
            <sequence-manager 
             className="org.apache.ojb.broker.util.sequence.SequenceManagerNativeImpl">
            </sequence-manager>
          </jdbc-connection-descriptor>
        	
          <class-descriptor class="org.appfuse.model.User" table="app_user">
            <field-descriptor name="id" column="id" 
             primarykey="true" autoincrement="true" access="readonly"/>
            <field-descriptor name="firstName" column="first_name"/>
            <field-descriptor name="lastName" column="last_name"/>
          </class-descriptor>
        </descriptor-repository>

That's pretty much it. Now you're using Spring, but because your system now uses and OJB class for ConnectionFactoryClass, you get to go back to using all the OJB stuff that you're used to. Works good.

NOTE: I got an email from Robert Sfier saying that it might not be a good idea to wrap transactin attributes around select-only (read) operations. That's a damn good point. Not point really using the Spring transaction system if you're doing a simple read and aren't worried about "select for update" or other concurrency kind-of stuff.

Note 2: Please also note that on the "Add User" function, you will see a new button. This button says, "Save and Fail Tx." Basically I've added a method that tries to insert two records with the same First Name name into the database. Since, in my the MySQL script I added UNIQUE to the first_name column, this will fail and roll the transaction back. This is just a "poor-man's" unit test to see transaction rollbacks with the Spring Framework system.

Please email me of post here if you have problems, questions, concerns.

Thanks,

Jason McKerr
The Open Source Lab
"Open Minds. Open Doors. Open Source."

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.7 Build:#524 Jul 28, 2006) - Bug/feature request - Contact Administrators