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

Trending

  • Security Challenges for Microservice Applications in Multi-Cloud Environments
  • Integration Architecture Guiding Principles, A Reference
  • Cypress Tutorial: A Comprehensive Guide With Examples and Best Practices
  • What Is mTLS? How To Implement It With Istio
  1. DZone
  2. Coding
  3. Java
  4. Extend Hibernate to Handle Java Stream Queries

Extend Hibernate to Handle Java Stream Queries

The Java Stream API released in Java 8 has proven itself to be an efficient, terse yet intuitive way of expressing application logic. The newly launched open...

Per-Åke Minborg user avatar by
Per-Åke Minborg
·
Julia Gustafsson user avatar by
Julia Gustafsson
·
Sep. 30, 20 · Tutorial
Like (5)
Save
Tweet
Share
1.22K Views

Join the DZone community and get the full member experience.

Join For Free
The Java Stream API released in Java 8 has proven itself to be an efficient, terse yet intuitive way of expressing application logic. The newly launched open-source project  JPAstreamer allows you to express Hibernate or other JPA database queries using Java Streams. In this article, we will show you how to extend the API of your existing database applications to handle Stream queries in an instant. 


To quickly give you an idea of what JPAstreamer accomplish, we'll start by showing you an example of a Stream operating on a database table that contains arbitrary users (with attributes including a first and last name):

Java
xxxxxxxxxx
1
 
1
jpaStreamer.stream(User.class)
2
    .filter(User$.firstName.startsWith("A"))
3
    .sort(User$.lastName.reversed())
4
    .limit(10)
5
    .forEach(System.out::println);


This will print ten users with a first name that starts with the letter A sorted in reversed order based on their last names. Omitting the details (that are covered shortly), this demonstrates how the desired result set is easily described as a pipeline of Stream operators.

On the surface, it may look as if the presented Stream would require every row in the User-table to be materialized in the JVM. Although, the Stream is actually optimized and rendered to JPA queries. Thus, the Stream queries are as performant as alternative approaches i.e. JPQL or Criteria Builder, but with the difference that JPAstreamer constitutes a streamlined and type-safe approach to expressing queries.

How JPAstreamer Works

JPAstreamer plugs into your application with the addition of a single dependency in your Maven/Gradle build. The specific dependency is described here.

Like the well-known Java library Lombok, JPAstreamer uses an annotation processor to form a meta-model at compile time. It inspects any classes marked with the standard JPA annotation @Entity and for every entity Foo.class, a corresponding Foo$.class is generated. The generated classes represent entity attributes as Fields that are used to form predicates on the form User$.firstName.startsWith("A") that can be interpreted by JPAstreamer's query optimizer.

It is important to note that JPAstreamer does not alter or disturb the existing codebase, but simply extends the API to handle Java Stream queries from this point forward. Further, the meta-model is placed in "generated sources" located in the "target" folder and doesn't need to be checked in with the source code nor tested.

Let's Get Streaming

We'll now walk you through the easy process of setting up JPAstreamer in your database application. To follow along, your application must use Java 8 (or later) and Hibernate or another JPA provider that is responsible for object persistence (if you wish to use the Stream API without JPA, you are better off using the open-source Stream ORM Speedment).

As mentioned, installation simply entails adding a dependency (described here) to your Maven/Gradle build and rebuilding the application to generate the JPAstreamer meta-model.

Once you've completed the simple set-up, you need to obtain an instance of JPAStreamer like so:

Java
xxxxxxxxxx
1
 
1
JPAStreamer jpaStreamer = JPAStreamer.of("db-name"); 


You should replace the String "db-name" with the name of the persistence unit you wish to query. Look it up in your JPA configuration-file (often named persistence.xml) under the tag <persistence-unit>.

The JPAstreamer instance provides access to the method .stream() that accepts the name of the Entity you wish to Stream. To query the user table, you would simply type:

Java
xxxxxxxxxx
1
 
1
jpaStreamer.stream(User.class)


This returns a stream of all the user rows of type Stream<User>. With a Stream source at hand, you are free to add any Java Stream operations to form a pipeline through which the data will flow (data flowing is a conceptual image rather than an actual description of how the code executes). For example:

Java
xxxxxxxxxx
1
 
1
List<String> users = jpaStreamer.stream(User.class)
2
    .filter(User$.age.greaterThan(20))
3
    .map(u -> u.getFirstName() + " " + u.getLastName())  
4
    .collect(Collectors.toList); 


This Stream collects the name of users who reached the age of 20 in a List. User$ refers to the generated entity that is part of JPAstreamer's meta-model. This entity is used to form predicates and comparators for operations such as .filter() and .sort() which are quickly composed leveraging code completion in modern IDEs.

Here is another example that counts all the users who are from Germany and are named "Otto" using a combined predicate:

Java
x
 
1
long count = jpaStreamer.stream(User.class) 
2
    .filter(User$.country.equal("Germany").and(User$.firstName.equal("Otto"))
3
    .count(); 

Conclusion

In this article, we have shown how you can integrate the open-source library JPAstreamer with Hibernate (or any JPA provider) to compose type-safe and expressive database queries as standard Java Streams.

Resources

  • GitHub: github.com/speedment/jpa-streamer
  • Homepage: jpastreamer.org
  • Documentation: github.io/jpa-streamer
  • Gitter Support Chat:gitter.im/jpa-streamer
Database Stream (computing) Java (programming language) Hibernate Open source application

Published at DZone with permission of Per-Åke Minborg, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Security Challenges for Microservice Applications in Multi-Cloud Environments
  • Integration Architecture Guiding Principles, A Reference
  • Cypress Tutorial: A Comprehensive Guide With Examples and Best Practices
  • What Is mTLS? How To Implement It With Istio

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

Let's be friends: