Spring ORM - Templates No Longer Recommended

   Posted by: Jim White

By Jim White (Director of Training and Instructor)

Spring 3 Changes - Not All About What Was Added

Spring 3 was a significant release that brought many new additions into the framework.  There is Spring Expression Language (SpEL), the type conversion system, formatting SPI, etc.  However, maybe just as important and possibly more impacting (especially to those that have "legacy" Spring code to support) is what was dropped from the Spring API.  The MVC controller hierarchy is the most often cited example of a big deprecation in Spring 3.

A more subtle change is Spring 3 is its treatment of object-relational mapping (ORM) packages like Hibernate, JDO, iBatis, and the like.  Gone (or more precisely as the Spring 3 documentation says - "no longer recommended") are the data access object (DAO) template classes.

Using the Spring 2.5 ORM Templates

In Spring 2.5 or earlier, you used the template method pattern to "wrap" the ORM persistence framework of choice.  Here are the pertinent parts (Spring XML configuration and DAO bean) of an example demonstrating the "old" template bean and its use in a DAO.

<bean id="myAnnotatedSessionFactory" class="org.springframework.orm. hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="myDataSource" />
</property>
<property name="annotatedClasses">
<list>
<value>com.intertech.domain.BallPlayer</value>
</list>
</property>
<property name="hibernateProperties">
<value>hibernate.dialect=org.hibernate.dialect.HSQLDialect</value>
</property>
</bean>
<bean id="myHibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="mySessionFactory" />
</property>
</bean>
<bean id="playerDao" class="com.intertech.dao.PlayerDao">
<property name="hibernateTemplate">
<ref bean="myHibernateTemplate" />
</property>
</bean>

public class PlayerDao {

private HibernateTemplate hibernateTemplate;

public void save(BallPlayer player) {
hibernateTemplate.save(player);
}
...
}

This form of ORM integration is now referred to in Spring 3 documentation as "classic ORM usage" (see the documentation here).  ORM templates, like the HibernateTemplate shown above, have not been deprecated, but they have been relegated to an appendix (Appendix A) in the Spring 3 documentation (see here).

Spring 3 ORM Integration

The recommended way to integrate your ORM of choice with Spring today "is to code DAOs against plain Hibernate, JPA, and JDO APIs."  The reason that the template objects are no longer recommended is not specified in the documentation.  However, a few blog articles (such as the one by Alef Arendsen here) provide us some insight on why the change was made.

First of all, checked exceptions are no longer thrown by most of the ORM frameworks.  This renders the template objects "useless" in some respects.  The underlying frameworks also handle transaction management and resource management concerns without the need for the template objects.

So today, Spring recommends you simply dependency inject the necessary factory and other data managing beans directly into your DAO beans.  Here is an example of the XML configuration and Spring 3 Repository/DAO bean using Hibernate.

<bean id="myAnnotatedSessionFactory" class="org.springframework.orm. hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="myDataSource" />
</property>
<property name="annotatedClasses">
<list>
<value>com.intertech.domain.BallPlayer</value>
</list>
</property>
<property name="hibernateProperties">
<value>hibernate.dialect=org.hibernate.dialect.HSQLDialect</value>
</property>
</bean>

@Repository
public class PlayerDao {

private SessionFactory sessionFactory;

@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}

public void savePlayer(Player player) {
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
session.save(player);
transaction.commit();
session.close();
}

...
}

OK - so if you look at the code closely, you can see the old templated-DAO has fewer lines of code (in this case to perform a save).  The template objects do more work behind the scenes and provide some convenience.  So, if shorter code is your chief concern, the "classic ORM usage" may be for you.  Of course, in order to use this classic approach, you have to more tightly couple your code to the Spring API -  something that even the Spring team frowns upon.

Exception Handling

While Hibernate, JPA, and other ORM frameworks now rely on runtime exceptions (versus checked exceptions), you are still going to want to take advantage of Spring's ORM exception translation capability.  That is, rather than having to catch and handle a JDBC (SQLException) or ORM specific exception in persistence code (the DAO bean), have Spring catch and wrap the native exception in a DataAccessException.  The DataAccessException still extends java.lang.Runtime exception, which means it does not have to be caught or re-thrown.   Optionally, it can be caught.  Furthermore, the DataAccessException is the root exception to a whole hierarchy (Spring defined) of exception types.  Spring converts the SQLException object into a more specific type of Exception.  The set of exception types provide more details to the application about the nature of the exception.  This allows developers to more easily provide meaningful recovery try/catch blocks for specific exception situations when needed - and the exception handling remains the same even if you change ORM frameworks!

How do you take advantage of Spring's ORM exception translation capability given the template objects are no longer recommended?  First, put all ORM code that might throw an ORM specific exception in a DAO object designated with an @Repository stereotype annotation (just like the DAO shown in the example above).  Secondly, register a BeanPostProcessor in your Spring configuration that advises all beans marked with the @Repository.

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

In particular, this post processor works with translators to intercept and convert ORM-specific exceptions.  These two steps enable Spring?s automatic ?exception translation? from ORM specific exceptions to DataAccessExceptions.

Moving to Spring 3

As mentioned, Spring 3 brings change, but not all change is about additions.  Some is about new ways of doing business.  As you get deeper into Spring 3 and consider migrating your applications to Spring 3, read the documentation.  For starters, you  may want to read the Spring 2.5 to 3.0 Upgrade Guide (found here).  Also, consider taking Intertech's Delta Spring 3 Framework class to learn about the "new" and "changed" APIs.  If you are new to Spring, I recommend you  take our Complete Spring 3 Framework class.  I just updated the content to cover all the latest features of Spring 2.5 and 3.0, but start you off from square 1.  We teach our classes out of the Twin Cities area, but most classes are available to virtually connected students as well.  You can attend the same class by Internet connection and see the class as it happens live through your computer monitor.  Come join us!


Comments (0)

Be the first one to comment on this post!

Add a Comment

*

*

Loading

Find Us
Contact Us 651-288-7000 1-800-866-9884
Home | Training | Curriculum | Course Finder | Schedule | Enroll | Twin Cities Java User Group | Consulting | Foundation | Jobs | About Us | Our Story | Press Room | Instructors | President | Map & Directions | Sitemap

Java Training | JSF / Struts / Spring / Hibernate Training | Java Power Tools Training | .NET 4.0 & Visual Studio 2010 Training | Microsoft Web Development Training | Prism / MVVM / MEF Training | .NET 3.5 and Visual Studio 2008 Training | .NET 2.0 and Visual Studio 2003 Training | Cloud Computing Training | Ajax / Web Services / XML Training | Groovy and Grails Training | SQL Server 2012 Training | SQL Server 2008 Training | SQL Server 2005 Training | Mobile Development Training | SharePoint 2010 Training | SharePoint 2007 Training | Agile, Process, Analysis & Design Training | Arch/Design Patterns Training | Microsoft Official Curriculum Training | Web Development Training | Ruby Training | Rational Application Developer (RAD) Training | WebSphere Application Server Training | WebSphere Portal Training | WebLogic Training | Boot Camp Training | Project Management Training | C / C++ Training | Metro / WinRT / Windows 8 Development Training | Retired

Intertech delivers training on-site and virtually serving cities including Phoenix, AZ | San Francisco, CA | Los Angeles, CA | San Diego, CA | San Jose, CA | Washington, DC | Chicago, IL | Orlando, FL | Boston, MA | Duluth, MN | Minneapolis St. Paul, MN | Rochester, MN | Raleigh-Durham, NC | New York, NY | Philadelphia, PA | Austin, TX | Dallas, TX | Houston, TX | Seattle, WA.