Awesome Spring Specification How-to

spring specification howto

Introduction

Okay so we made a filterable + sortable + pageable list before with Spring + Couchbase (you can read more about it here and here, I totally recommend you read those posts, cuz I’ll refer to them in this one).

Actually filters are meant to be in an AND relation between the parameters (most of the cases). But what if you want to add some ORs to your query? Or you want to filter on multiple columns by only one input field from the request parameter? I’ll show you how to implement an API easily, which is the resource for a filterable + sortable + pageable with more complext filter conditions.

SPRING framework filterable list

Controller

As always, let’s start our journey at the controller

Pretty much the same as in the CouchbaseQueryExecutor example app, but I know now that you can pass a Java Class parameter to the controller function, so Spring will automatically fill the properties from the query string. In case of name collision, all of the properties with the same name will be filled. IMPORTANT if you want to use yout Java class like this it MUST have setters. In case you don’t add setters, then spring won’t bind the parameters to the properties (even if the properties are public).

So yeah, with this little difference our contorller looks the same (using vavr ofc (smile)).

Service

Let’s continue with the service

Pretty much the same again, we pass the filters and the pageable param to the service from the controller, and after we acquired the Entities we map it to Dtos. The UserListSpecification is the class where the magic happens (smile).

Repository

But before the UserListSpecification – let’s take a look at the UserRepository.

Again and again, the same… With a little difference: now our UserRepository extends the JpaSpecificationExecutor, so we can filter our entities by a Specification with the following function

All we have to do is make a specification from the UserListRequest. Let’s se how to do it.

Specification

I’m not going to talk too much about it, I think the code is self explanatory enough (smile)

As it’s a higher level function, first you define the AND and OR relations with the specific parentheses (the example above is (firstName OR lastName OR email) AND street AND city).

We need the ‘query.distinct(true);’ because one user can have multiple addresses. To filter the address properties, you have to join addresses to users. What happens on the JPA level when you filter on addresses, and want to receive users with specific addresses? Let’s assume we have the following data in the database

So John Doe has 3 addresses in Budapest. Now if we join the two tables we’ll get 3 records, each containing John Doe’s data with each of the addresses. After that, if you return with only the users (in this case only John Doe), you’ll get that one user 3 times as result. So if you only want to get distinct result, then you should add that magical line. If you only want to filter users for example, you can have the specification like this:

Let’s assume we have the first specification (with the addresses). Our request contains a search property which should filter on firstName, lastName and email column, and a city/street property that should filter on city/street. Only one thing remains before our our API is complete: tell JPA how to filter on the columns.

All in all – Spring specification how-to

I wanted to make my example as clear as possible, so I didn’t add a lot of conditions with complex logic, just made a simple example application. If you want to know more about CriteriaBuilder take a look at its API.

After you added all of these, you can try your API with you favoirite REST client with the following URL:

(all parts of the query string are optional).

 

So if you need the entire source code to try these things out for yourself, look at the GitHub project!

If you wanna see more stuff from us, follow our Facebook or Twitter.

I hope this post was useful for you, see ya later! (smile)

Alex Sükein

Alex Sükein

- Süxy, can you tell me about robust software development Nasa uses?
- Yes. If we have a final exam tomorrow.