DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Getting Started With JPA/Hibernate
  • Upgrade Guide To Spring Boot 3.0 for Spring Data JPA and Querydsl
  • Spring Boot: How To Use Java Persistence Query Language (JPQL)
  • Simplify Java Persistence Using Quarkus and Hibernate Reactive

Trending

  • Automated Testing Lifecycle
  • TDD With FastAPI Is Easy
  • Automated Testing: The Missing Piece of Your CI/CD Puzzle
  • LTS JDK 21 Features
  1. DZone
  2. Data Engineering
  3. Databases
  4. The Persistence Layer with Spring 3 and Hibernate 4

The Persistence Layer with Spring 3 and Hibernate 4

Eugen Paraschiv user avatar by
Eugen Paraschiv
·
Dec. 20, 11 · Interview
Like (3)
Save
Tweet
Share
42.66K Views

Join the DZone community and get the full member experience.

Join For Free

This is the first of a series of articles about Persistence with Spring. This article will focus on the configuration and implementation of the persistence layer with Spring 3.1 and Hibernate. For a step by step introduction about setting up the Spring context using Java based configuration and the basic Maven pom for the project, see this.

The Persistence with Spring series:

  • Part 1 – The Persistence Layer with Spring 3.1 and Hibernate
  • Part 2 – Simplifying the Data Access Layer with Spring and Java Generics
  • Part 3 – The Persistence Layer with Spring 3.1 and JPA
  • Part 4 – The Persistence Layer with Spring Data JPA
  • Part 5 – Transaction configuration with JPA and Spring 3.1

No More Spring Templates

Starting Spring 3.0 and Hibernate 3.0.1, managing the Hibernate Session with Springs HibernateTemplate is no longer necessary. It is now possible to make use of contextual sessions – sessions managed directly by Hibernate and kept active throughout the scope of a transaction.

As a consequence, it is now best practice to use the Hibernate API directly instead of the HibernateTemplate, which will effectively decouple the DAO layer implementation from Spring entirely.

Exception Translation without the template

One of the responsibilities of HibernateTemplate is exception translation – translating the low level Hibernate exceptions – which tie the API to Hibernate as the single possible ORM – into higher level, generic Spring exceptions.

Without the template to do that, exception translation can still be enabled by annotating the DAOs with the @Repository annotation. That, coupled with a Spring bean postprocessor will advice all @Repository beans with all the implementations of PersistenceExceptionTranslator found in the Spring context – to provide exception translation without using the template.

Exception translation is done through proxies; in order for Spring to be able to create proxies around the DAO classes, these must not be declared final.

Hibernate Session management without the template

When Hibernate support for contextual sessions came out, the HibernateTemplate essentially became obsolete; in fact, the javadoc of the class has been updated with this advice (bold from the original):

NOTE: As of Hibernate 3.0.1, transactional Hibernate access code can also be coded in plain Hibernate style. Hence, for newly started projects, consider adopting the standard Hibernate3 style of coding data access objects instead, based on {@link org.hibernate.SessionFactory#getCurrentSession()}.

The Spring Java configuration

The Hibernate SessionFactory is set up in the configuration by creating a Spring factory bean to manage it – the AnnotationSessionFactoryBean; this will enable autodetection of the entity classes by classpath scanning. Note that this requires Hibernate 3.2+ and JDK 1.5+.

The alternative is to manually specify all the annotated entity classes to the session factory bean, by using the setAnnotatedClasses method.

@Configuration
@EnableTransactionManagement
public class PersistenceHibernateConfig{
   
   @Bean
   public AnnotationSessionFactoryBean alertsSessionFactory(){
      AnnotationSessionFactoryBean sessionFactory = new AnnotationSessionFactoryBean();
      sessionFactory.setDataSource( this.restDataSource() );
      sessionFactory.setPackagesToScan( new String[ ] { "org.rest" } );
      sessionFactory.setHibernateProperties( this.hibernateProperties() );
      
      return sessionFactory;
   }
   @Bean
   public DataSource restDataSource(){
      DriverManagerDataSource dataSource = new DriverManagerDataSource();
      dataSource.setDriverClassName( this.driverClassName );
      dataSource.setUrl( this.url );
      dataSource.setUsername( "restUser" );
      dataSource.setPassword( "restmy5ql" );
      
      return dataSource;
   }
   @Bean
   public HibernateTransactionManager transactionManager(){
      HibernateTransactionManager txManager = new HibernateTransactionManager();
      txManager.setSessionFactory( this.alertsSessionFactory().getObject() );
      
      return txManager;
   }
   @Bean
   public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
      return new PersistenceExceptionTranslationPostProcessor();
   }

}

Also, note that cglib must be on the classpath for Java @Configuration classes to work; to better understand the need for cglib as a dependency, see this article.

The Spring XML configuration

The same Spring configuration with XML:

<bean id="sessionFactory" class=
    "org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
   <property name="dataSource" ref="dataSource" />
   <property name="packagesToScan" value="org.rest" />
   
   <property name="hibernateProperties">
      ...
   </property>
</bean>
<bean id="dataSource" class=
    "org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName" value="${driverClassName}" />
   <property name="url" value="${url}" />
   <property name="username" value="restUser" />
   <property name="password" value="restmy5ql" />
</bean>

<bean id="txManager" class=
    "org.springframework.orm.hibernate3.HibernateTransactionManager">
   <property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />

There is a relatively small difference between the way Spring is configured in XML and the new Java based configuration – in XML, a reference to another bean can point to either the bean or a bean factory for that bean. In Java however, the compiler wouldn’t allow that, and so the SessionFactory is first retrieved from it’s factory and then passed to the transaction manager:

transactionManager.setSessionFactory( this.alertsSessionFactory().getObject() );

The Hibernate Properties

Hibernate is configured to work with Spring by using the following Hibernate properties:

hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=false

Note that the MySQL dialect is included as a reference, but any Hibernate supported dialect will do.

Potential for Exceptions

The Transaction Factory

The Hibernate contract for creating transactions is specified by the TransactionFactory interface. In order for Spring to fully manage transactions, the default implementation of this contract – JDBCTransactionFactory – is replaced by default with it’s Spring-aware counterpart – SpringTransactionFactory.

This can also be done manually, in the Hibernate properties (it is however redundant):

transaction.factory_class=org.springframework.orm.hibernate3.SpringTransactionFactory

The Current Session Context

When the Hibernate SessionFactory is created in the Spring context by it’s factory bean, it will create the CurrentSessionContext. This is the contract for supporting the current session concept and its implementation is decided by analyzing the “hibernate.current_session_context_class” Hibernate property.

Setting this property to “managed” means using the managed implementation for contextual sessions – ManagedSessionContext – which assumes that the current session is managed by an external entity. In our Spring context, that would fail with:

org.springframework.orm.hibernate3.HibernateSystemException: No session currently bound to execution context

Setting the property to “thread” would enable the thread-bound strategy in the Hibernate configuration; this would also conflict with Spring Transaction management and would result in:

org.springframework.orm.hibernate3.HibernateSystemException: persist is not valid without active transaction

To let Spring manage transactions, this property needs to be “org.springframework.orm.hibernate3.SpringSessionContext”; because this is also the default, the explicit definition of the property can be removed.

The DAO

Each DAO will be based on an parametrized, abstract DAO class class with support for the common generic operations:

public abstract class AbstractHibernateDAO< T extends Serializable >{
   private final Class< T > clazz;
   
   @Autowired
   SessionFactory sessionFactory;
   
   public void setClazz( final Class< T > clazzToSet ){
      this.clazz = clazzToSet;
   }
   
   public T getById( final Long id ){
      Preconditions.checkArgument( id != null );
      return (T) this.getCurrentSession().get( this.clazz, id );
   }
   public List< T > getAll(){
      return this.getCurrentSession()
       .createQuery( "from " + this.clazz.getName() ).list();
   }
   
   public void create( final T entity ){
      Preconditions.checkNotNull( entity );
      this.getCurrentSession().persist( entity );
   }
   
   public void update( final T entity ){
      Preconditions.checkNotNull( entity );
      this.getCurrentSession().merge( entity );
   }
   
   public void delete( final T entity ){
      Preconditions.checkNotNull( entity );
      this.getCurrentSession().delete( entity );
   }
   public void deleteById( final Long entityId ){
      final T entity = this.getById( entityId );
      Preconditions.checkState( entity != null );
      this.delete( entity );
   }
   
   protected final Session getCurrentSession(){
      return this.sessionFactory.getCurrentSession();
   }
}

A few aspects are interesting here – as discussed, the abstract DAO does not extend any Spring template (such as HibernateTemplate). Instead, the Hibernate SessionFactory is injected directly in the DAO, and will have the role of the main Hibernate API, through the contextual Session it exposes:

this.sessionFactory.getCurrentSession();

Also, note that the entity Class is passed in the constructor to be used in the generic operations:

@Repository
public class FooDAO extends AbstractHibernateDAO< Foo > implements IFooDAO{
   
   public FooDAO(){
      setClazz(Foo.class );
   }
   
}

The Maven configuration

In addition to the Maven configuration defined in a previous article, the following dependencies are addeed: spring-orm (which also has spring-tx as its dependency) and hibernate-core:

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-orm</artifactId>
   <version>3.2.2.RELEASE</version>
</dependency>
<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>4.2.0.Final</version>
</dependency>

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.24</version>
   <scope>runtime</scope>
</dependency>

Note that the MySQL dependency is included as a reference – a driver is needed to configure the datasource, but any Hibernate supported database will do.

Conclusion

This article covered the configuration and implementation of the persistence layer with Hibernate and Spring 3.1, using both XML and Java based configuration. The reasons to stop relying on templates for the DAO layer was discussed, as well as possible pitfalls of configuring Spring to manage transactions and the Hibernate Session. The final result is a lightweight, clean DAO implementation, with almost no compile-time reliance on Spring. You can check out the full implementation in the github project.

I don't want your learning about Spring Persistence to stop here.
>> Get my "Spring Persistence" eBook and subscribe to my Email List
Spring Framework Hibernate Persistence (computer science)

Published at DZone with permission of Eugen Paraschiv, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Getting Started With JPA/Hibernate
  • Upgrade Guide To Spring Boot 3.0 for Spring Data JPA and Querydsl
  • Spring Boot: How To Use Java Persistence Query Language (JPQL)
  • Simplify Java Persistence Using Quarkus and Hibernate Reactive

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: