One of the sweetiest things the Spring
framework gives is Hibernate support is built-in by the time it's born.
Following is a quick guide to configure Hibernate's SessionFactory in Spring.
For a detailed version about Spring's Hibernate support, read http://www.springframework.org/docs/data_access.html.
With Spring, Hibernate's SessionFactory no longer needs to bind itself to JNDI;
nor use Hibernate's own hibernate.cfg.xml method, which is a little bit tricky
to code in Hibernate 2.x (as Hibernate2 doesn't use the once-and-only-once
configure() anymore).
Instead, we use org.springframework.orm.hibernate.LocalSessionFactoryBean.
|
|
The above parameters are simple and verbose:
mappingResources: specifies a list of
Hibernate's mapping XML files. The files' search path in JARs are
identical to what Hibernate do. hibernateProperties: specify the properties to
be set for Hibernate's SessionFactory. They are identical to these: http://www.hibernate.org/hib_docs/reference/html/session-configuration.html#session-configuration-s5
dataSource: the DataSource used by the
SessionFactory.However, we don't need to
configure a transaction manager inside the SessionFactory, as we will
see below.
After configuring this, we need to provide a setter method in our business
objects that need to use Hibernate's SessionFactory:
|
|
and hook it up to Spring.
|
|
That's Spring framework's another
power - HibernateInterceptor and TransactionInterceptor. With them, together
with configurations made in Spring, methods inside business objects don't need
to write a single line of code for that; instead, a Session will be bound to
the business object's current thread, opened and closed automatically; and a
transaction will also begin and end automatically.
The sequence is like this:
This is done with the help of
Spring's AOP capability.
However, we need to configure a transaction manager first.
|
|
The above configures a transaction manager that will access an UserTransaction
inside the environment, usually in a J2EE container, or a servlet container
with transaction support.
Alternately you may want to have a look at org.springframework.orm.hibernate.HibernateTransactionManager.
Next, we need to define the transaction attribute for our business methods.
This is done in org.springframework.transaction.interceptor.TransactionInterceptor?.
|
|
You can use a wildcard to tell
every method in that business object uses the same transaction attribute.
However it is not recommended, as the private methods used inside the business
object will have transactions too, which you may not need to.
By the way, the TransactionInterceptor's default behaviour is to commit an
transaction anyway, and rollback whenever a RuntimeException is caught - much
the same as EJB's behaviour. If you want to control TransactionInterceptor's
behaviour when exception is caught, you may tell it with a plus (+) or minus
(-) sign, followed by the name of the exception, to commit or rollback a
transaction even if an exception mentioned is caught.
An example:
|
|
This means that when SeriesNotFoundException is thrown inside the addBook()
method, the transaction will roll back; on the other hand when
CategoryNotFoundException is thrown the transaction will be commited anyway.
In most cases you don't need to specify the exception's name with the package
it belongs; you just need to specify simply the exception's name.
Then our business objects will need to define as an AOP "target".
This is just a change in a name; make sure your code will not call these
business objects directly. So change the above business object declaration to
|
|
Final step is to expose the business object on Spring's ApplicationContext, but
not the business object itself; instead we use a ProxyFactoryBean, provided by
Spring.
|
|
Then in our business method we
just need to obtain the Session instance, and ignore everything else -
everything is done behind the scene.
|
|
Alternately you may also use HibernateTemplate and TransactionTemplate, though the above method is simpler. Read http://www.hibernate.org/110.html for details (this page seems more updated than the one in Spring?).