The Spring and Hibernate Harmony


The Spring Framework provides first class integration with Hibernate. Some of the benefits of integrating these two technologies include ease of testing, consistent data exceptions (for example, DataIntegrityViolationException), and one key benefit for our specific needs, declarative transaction management in light-weight containers! (For details on the benefits of the Spring and Hibernate integration, refer to the Spring Reference Documentation on the springframework.org website.)

Now let's look at how we can leverage Spring to provide us declarative transaction management features, thereby shifting the burden to the Spring container and allowing us to focus on business logic (declarative transaction management is discussed in detail later in the chapter).

We will also see how using declarative transaction management will cut down the lines of code in some of our model package classes to almost half!

Configuring Transaction Management in Spring

Until now, we have been looking at the Time Expression under the timex/ directory. However, this book's code zip file also contains a refactored version of this application under a timex2/ directory; incidentally, this is also the code base that demonstrates the Spring and Hibernate integration, so we will analyze some of the files under this directory next.

The Java code refactoring is discussed in Appendix B, "Refactoring Done to Sample Application." Here, we will walk through the changes we made to our timex-servlet.xml file, now renamed to timex2-servlet.xml (found under the timex2/ directory).

Reconfiguring Our Sample Application

Figure 10.3 shows how our controller classes (in timex/) use the manager classes directly; for example, notice how our EnterHoursController class uses DepartmentManager directly. This direct approach is further demonstrated in the following XML configuration from our original timex-servlet.xml file:

<bean name="enterHoursController"     >     <property name="departmentManager">         <ref bean="departmentManager" />     </property>


Figure 10.3. Graphical view of timex-servlet.xml.


By using the manager classes directly, we had to implement our own transaction managementin other words, programmatic transaction management.

Now, let's look at how we will work with our manager classes indirectly; that is, via transaction proxy bean classes.

Figure 10.4 shows a Spring IDE graph for the EnterHoursController and related beans as they are defined in our refactored timex2-servlet.xml file. Notice how the EnterHoursController class now goes through a proxy bean named departmentManagerProxy (a Spring TRansactionProxyFactoryBean class). This proxy bean provides us two primary benefits:

  • Management of Hibernate sessions so we don't have to worry about closing the Hibernate session manually.

  • Declarative transaction management inside light-weight containers with the capability to scale down to single database transactions or scale up to global Java Transaction API (JTA) based transactions. Spring even provides special transaction manager support classes (for example, WebLogicJtaTransactionManager) for products such as ObjectWeb's Java Open Transaction Manager (JOTM; jotm.objectweb.org), BEA's WebLogic application server (bea.com), and IBM's WebSphere application server (ibm.com).

    Figure 10.4. Graphical view of timex2-servlet.xml.

Now let's review the code behind the graph shown in Figure 10.4.

Less and Cleaner Java Code!

One of the key benefits of declarative transaction management I mentioned earlier is that the burden of transaction management is shifted to the container. This also translates into reduced code, which in turn enables us to focus on business logic more than low-level plumbing-type coding such as transaction management. This feature has been available in Enterprise JavaBeans for sometime now, but as I mentioned earlier, by using Spring, we get the same facilities of enterprise transaction management in light-weight containers such as Apache Tomcat.

The following original code excerpt shows our saveTimesheet(Timesheet timesheet) method from the existing Time Expression's TimesheetManager class (found under the timex/ directory). This uses Hibernate's programmatic transaction management.

Session session = HibernateUtil.getSessionFactory()         .getCurrentSession(); session.beginTransaction(); try {     session.saveOrUpdate(timesheet);     session.getTransaction().commit(); } catch (HibernateException e) {     session.getTransaction().rollback();     throw e; }


Note

Appendix B demonstrates the code changes discussed in this section.


The same code can be reduced to the following single line of code using Spring (demonstrated in the TimesheetManagerImpl1 class under the springhibernate/ directory):

this.sessionFactory.getCurrentSession().merge(timesheet);


Alternatively, we can extend Spring's HibernateDaoSupport support class, which enables us to reduce our Java code even further by eliminating the getSessionFactory and setSessionFactory methods. Furthermore, the Hibernate exceptions are automatically translated into a consistent data exception hierarchy.

HibernateDaoSupport provides a method named getHibernateTemplate that provides methods typically found in Hibernate's Session interface, as shown here:

getHibernateTemplate().merge(timesheet);


Our three manager classes, DepartmentManager, EmployeeManager, and TimesheetManager, have now been refactored (in the timex2/ directory) to extend the HibernateDaoSupport class. As a result, these classes combined have 126 fewer lines of code now! Table 10.1 shows the comparison of the number of lines of code in these three class files using both types of transaction management.

Table 10.1. Lines of Code for Programmatic Versus Declarative Transaction Management

File

Programmatic

Declarative

DepartmentManager.java

39

22

EmployeeManager.java

66

36

TimesheetManager.java

166

87

TOTAL

271

145


If only three simple classes can cut down so much code, imagine how many fewer lines of code we would have in a typical real-world enterprise Java application with many more classes in this category (that is, service layer).

Although HibernateDaoSupport provides some benefits, there are also some minor drawbacks to consider, including the following:

  • It tightly couples Hibernate and Spring, so if Hibernate provides an upgrade that Spring doesn't support, we would have to wait for the Spring Framework to be updated.

  • Because Java supports only single inheritance, after we extend HibernateDaoSupport, our only shot at extending another class is lost; of course, we could extend our own custom class, which in turn could extend HibernateDaoSupport to get around this limitation.

Nevertheless, the benefits discussed earlier would appear to outweigh the minor drawbacks.

Unit Testing Our Integrated Code

Now that we are using a new style of transaction management in the timex2/ related refactored code, we also need to use these classes differently in our unit tests. For example, to use one of our manager classes, we must now load the proxy bean instead, as demonstrated in this code excerpt from our TimexTestCase class:

FileSystemResource res =     new FileSystemResource("src/conf/timex2-servlet.xml"); springFactory = new XmlBeanFactory(res); departmentManager =     (DepartmentManager)springFactory.getBean("departmentManagerProxy");


Interface-Based Approach

Incidentally, there is another project bundled in this book's code zip file, under the springhibernate/ directory (see filenames in Appendix A, "Downloadable Code for This Book"). This project demonstrates two things:

  • How to configure and code using interfaces with implementation classes.

  • How to force a org.springframework.dao. DataIntegrityViolationException exception to see how Spring's consistent data exception works and also how the Spring Web Framework can redirect the user to a view (dberror.jsp, in our case) for a given mapped exception.

One thing to note about this demo: Because it uses an interface-based approach (versus the class-based approach used in Time Expression), we do not need to use the proxyTargetClass attribute, as we do in our timex2-servlet.xml file.

<bean      class=     "org.springframework.transaction.interceptor. TransactionProxyFactoryBean">     <property name="proxyTargetClass" value="true"/>


Figure 10.5 shows a graphical view of the Spring application context file, springhibernate-servlet.xml, used in this demo. Notice that the proxyTargetClass attribute is not used in the proxy classes.

Figure 10.5. Graphical view of springhibernate-servlet.xml.


Note

There is one feature of Eclipse worth pointing out here. Notice on the left side of Figure 10.5 how Eclipse enables us to work with multiple projects in the same workspace; in this case, we are working with our three projects: springhibernate, timex, and timex2.




Agile Java Development with Spring, Hibernate and Eclipse
Agile Java Development with Spring, Hibernate and Eclipse
ISBN: 0672328968
EAN: 2147483647
Year: 2006
Pages: 219

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net