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 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
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
Partner Zones AWS Cloud
by AWS Developer Relations
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
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Data Engineering
  3. Databases
  4. Easier JPA with Spring Data JPA

Easier JPA with Spring Data JPA

Nicolas Fränkel user avatar by
Nicolas Fränkel
CORE ·
Jul. 02, 12 · Interview
Like (1)
Save
Tweet
Share
49.26K Views

Join the DZone community and get the full member experience.

Join For Free
Database access in Java went through some steps:
  • at first, pure JDBC
  • proprietary frameworks
  • standards such as EJB Entities and JDO
  • OpenSource frameworks such as Hibernate and EclipseLink (known as TopLink at the time)
When JPA was finally released, it seemed my wishes came true. At last, there was a standard coming from the trenches to access databases in Java Unfortunately, JPA didn't hold its promises when compared to Hibernate: for example, you don't have Query by Example. Even worse, in its first version, JPA didn't provide simple features like Criteria, so that even simple queries would have to be implemented through JPQL and thus achieved with String concatenation. IMHO, this completely defeated ORM purposes.

JPA2 to the rescue

At last, JPA2 supplies something usable in a real-world application. And yet, I feel there's still so much boilerplate code to write a simple CRUD DAO:
public class JpaDao<E, PK> {

    @PersistenceContext
    private EntityManager em;

    private Class<E> managedClass;

    private JpaDao(Class<E> managedClass) {

        this.managedClass = managedClass;
    }

    public void persist(E entity) {

        em.persist(entity);
    }

    public void remove(E entity) {

        em.remove(entity);
    }

    public E findById(PK id) {

        return em.find(managedClass, id);
    }
}
Some would (and do) object that in such a use-case, there's no need for a DAO: the EntityManager just needs to be injected in the service class and used directly. This may be a relevant point-of-view, but only when there's no query for as soon as you go beyond that, you need to separate between data access and business logic.

Boilerplate code in JPA2

Two simple use-cases highlight the useless boilerplate code in JPA 2: @NamedQuery and simple criteria queries. In the first case, you have to get the handle on the named query through the entity manager, then set potential parameters like so:
Query query = em.createNamedQuery("Employee.findHighestPaidEmployee");
  In the second, you have to implement your own query with the CriteriaBuilder:
CriteriaBuilder builder = em.getCriteriaBuilder();

CriteriaQuery<Person> query = builder.createQuery(Person.class);

Root<Person> fromPerson = query.from(Person.class);

return em.createQuery(query.select(fromPerson)).getResultList();
 IMHO, these lines of code bring nothing to the table and just clutter our own code. By chance, some time ago, I found project Hades, a product which was based on this conclusion and wrote simple code for you.

Spring Data JPA

Given the fate of some excellent OpenSource projects, Hades fared much better since it has been brought into the Spring ecosystem under the name Spring Data JPA. Out of the box, SDJ provides DAOs that have advanced CRUD features. For example, the following interface can be used as-is: [java]public interface EmployeeRepository extends JPARepository[/java] Given some Spring magic, an implementation will be provided at runtime with the following methods:
  • void deleteAllInBatch()
  • void deleteInBatch(Iterable<Employee> entities)
  • List<Employee> findAll()
  • List<Employee> findAll(Sort sort)
  • void flush()
  • <S extends Employee> List<S> save(Iterable<S> entities)
  • Employee saveAndFlush(Employee entity)
  • Page<Employee> findAll(Pageable pageable)
  • Iterable<Employee> findAll(Sort sort)
  • long count()
  • void delete(ID id)
  • void delete(Iterable<? extends Employee> entities)
  • void delete(Employee entity)
  • void deleteAll()
  • boolean exists(Long id)
  • Iterable<Employee> findAll()
  • Iterable<Employee> findAll(Iterable ids)
  • Employee findOne(Long id)
  • <S extends Employee> Iterable<S> save(Iterable<S> entities)
  • <S extends Employee> S save(S entity)
Yes, SDJ provides you with a generic DAO, like so many frameworks around but here, wiring into the underlying implementation is handled by the framework, free of charge. For those that don't need them all and prefer the strict minimum, you can also use the following strategy, where you have to choose the methods from the list above (and use the annotation):
]@RepositoryDefinition(domainClass = Employee.class, idClass = Long.class)
public interface EmployeeRepository {

    long count();

    Employee save(Employee employee);
}
It sure is nice, but the best is yet to come. Remember the two above use-cases we had to write on our own? The first is simply handled by adding the unqualified query name to the interface like so:
@RepositoryDefinition(domainClass = Employee.class, idClass = Long.class)
public interface EmployeeRepository {

    ...

    Employee findHighestPaidEmployee();
}
 The second use-case, finding all employees, is provided in the JPA repository. But let's pretend for a second we have a WHERE clause, for example on the first name. SDJ is capable of handling simple queries based on the method name:
@RepositoryDefinition(domainClass = Employee.class, idClass = Long.class)
public interface EmployeeRepository {

    ...

    List<Employee> findByLastname(String firstName);
}
We had to code only an interface and its methods: no implementation code nor metamodel generation was involved! Don't worry, if you need to implement some complex queries, SDJ let you wire your own implementation.

Conclusion

If you're already a Spring user, Spring Data JPA is really (really!) a must. If you're not, you're welcome to test it to see its added value by yourself. IMHO, SDJ is one of the reason JavaEE has not killed Spring yet: it bridged the injection part, but the boilerplate code is still around every corner. This article is not a how-to but a teaser to let you into SDJ. You can find the sources for this article here, in Maven/Eclipse format. To go further:
  • Spring Data JPA documentation
  • Spring Data JPA Javadocs
For those that aren't into JPA yet, there's Data JDBC; for those that are well beyond that (think Big Data); there's a Data Hadoop. Check all of Spring Data projects!
Spring Data Spring Framework Data (computing) Database

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Utilizing Database Hooks Like a Pro in Node.js
  • 7 Ways for Better Collaboration Among Your Testers and Developers
  • Getting a Private SSL Certificate Free of Cost
  • 5 Steps for Getting Started in Deep Learning

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

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: