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
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
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

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • What Java DAO Layer Is Best for Your Project
  • Mastering Persistence: Why the Persistence Layer Is Crucial for Modern Java Applications
  • Effective Java Collection Framework: Best Practices and Tips
  • Architecture and Code Design, Pt. 2: Polyglot Persistence Insights To Use Today and in the Upcoming Years

Trending

  • Scalability 101: How to Build, Measure, and Improve It
  • Setting Up Data Pipelines With Snowflake Dynamic Tables
  • Start Coding With Google Cloud Workstations
  • Why I Started Using Dependency Injection in Python
  1. DZone
  2. Data Engineering
  3. Data
  4. Simplifying the Data Access Layer with Spring and Java Generics

Simplifying the Data Access Layer with Spring and Java Generics

By 
Eugen Paraschiv user avatar
Eugen Paraschiv
·
Jan. 05, 12 · Interview
Likes (1)
Comment
Save
Tweet
Share
24.6K Views

Join the DZone community and get the full member experience.

Join For Free

1. Overview

This is the second of a series of articles about Persistence with Spring. The previous article discussed setting up the persistence layer with Spring 3.1 and Hibernate, without using templates. This article will focus on simplifying the Data Access Layer by using a single, generified DAO, which will result in elegant data access, with no unnecessary clutter. Yes, in Java.

The Persistence with Spring series:

  • Part 1 – The Persistence Layer with Spring 3.1 and Hibernate
  • 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

2. The DAO mess

Most production codebases have some kind of DAO layer. Usually the implementation ranges from a raw class with no inheritance to some kind of generified class, but one thing is consistent – there is always more then one. Most likely, there are as many DAOs as there are entities in the system. Also, depending on the level of generics involved, the actual implementations can vary from heavily duplicated code to almost empty, with the bulk of the logic grouped in an abstract class.

2.1. A Generic DAO

Instead of having multiple implementations – one for each entity in the system – a single parametrized DAO can be used in such a way that it still takes full advantage of the type safety provided by generics.

Two implementations of this concept are presented next, one for a Hibernate centric persistence layer and the other focusing on JPA. These implementation are by no means complete – only some data access methods are included, but they can be easily be made more thorough.

2.2. The Abstract Hibernate DAO

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

The DAO uses the Hibernate API directly, without relying on any Spring templates (such as HibernateTemplate). Using of templates, as well as management of the SessionFactory which is autowired in the DAO were covered in the previous post of the series.

2.3. The Abstract JPA DAO

public abstract class AbstractJpaDAO< T extends Serializable > {
   
   private Class< T > clazz;
   
   @PersistenceContext
   EntityManager entityManager;
   
   public void setClazz( Class< T > clazzToSet ){
      this.clazz = clazzToSet;
   }
   
   public T findOne( Long id ){
      return this.entityManager.find( this.clazz, id );
   }
   public List< T > findAll(){
      return this.entityManager.createQuery( "from " + this.clazz.getName() )
       .getResultList();
   }
   
   public void save( T entity ){
      this.entityManager.persist( entity );
   }
   
   public void update( T entity ){
      this.entityManager.merge( entity );
   }
   
   public void delete( T entity ){
      this.entityManager.remove( entity );
   }
   public void deleteById( Long entityId ){
      T entity = this.getById( entityId );
      
      this.delete( entity );
   }
}

Similar to the Hibernate DAO implementation, the Java Persistence API is used here directly, again not relying on the now deprecated Spring JpaTemplate.

2.4. The Generic DAO

Now, the actual implementation of the generic DAO is as simple as it can be – it contains no logic. Its only purpose is to be injected by the Spring container in a service layer (or in whatever other type of client of the Data Access Layer):

@Repository
@Scope( BeanDefinition.SCOPE_PROTOTYPE )
public class GenericJpaDAO< T extends Serializable >
 extends AbstractJpaDAO< T > implements IGenericDAO< T >{
   //
}

@Repository
@Scope( BeanDefinition.SCOPE_PROTOTYPE )
public class GenericHibernateDAO< T extends Serializable >
 extends AbstractHibernateDAO< T > implements IGenericDAO< T >{
   //
}

First, note that the generic implementation is itself parametrized – allowing the client to choose the correct parameter in a case by case basis. This will mean that the clients gets all the benefits of type safety without needing to create multiple artifacts for each entity.

Second, notice the prototype scope of these generic DAO implementation. Using this scope means that the Spring container will create a new instance of the DAO each time it is requested (including on autowiring). That will allow a service to use multiple DAOs with different parameters for different entities, as needed.

The reason this scope is so important is due to the way Spring initializes beans in the container. Leaving the generic DAO without a scope would mean using the default singleton scope, which would lead to a single instance of the DAO living in the container. That would obviously be majorly restrictive for any kind of more complex scenario.

3. The Service

There is now a single DAO to be injected by Spring; also, the Class needs to be specified:

@Service
class FooService implements IFooService{
   
   IGenericDAO< Foo > dao;
   
   @Autowired
   public void setDao( IGenericDAO< Foo > daoToSet ){
      this.dao = daoToSet;
      this.dao.setClazz( Foo.class );
   }
   
   // ...
   
}

Spring autowires the new DAO insteince using setter injection so that the implementation can be customized with the Class object. After this point, the DAO is fully parametrized and ready to be used by the service.

4. Conclusion

This article discussed the simplification of the Data Access Layer by providing a single, reusable implementation of a generic DAO. This implementation was presented in both a Hibernate and a JPA based environment. The result is a streamlined persistence layer, with no unnecessary clutter.

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 article. The next article of the Persistence with Spring series will focus on setting up the DAL layer with Spring 3.1 and JPA. In the meantime, you can check out the full implementation in the github project.

If you read this far, you should follow me on twitter here.

Spring Framework Data access layer Data access Data (computing) Decentralized autonomous organization Java (programming language) Implementation 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

  • What Java DAO Layer Is Best for Your Project
  • Mastering Persistence: Why the Persistence Layer Is Crucial for Modern Java Applications
  • Effective Java Collection Framework: Best Practices and Tips
  • Architecture and Code Design, Pt. 2: Polyglot Persistence Insights To Use Today and in the Upcoming Years

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • 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:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!