Spring Security with Spring Boot 2.0: Securing your endpoints

Up until now in our previous posts we had our endpoints and controllers secured using the default spring security configuration.
When Spring Security is on the classpath, the auto-configuration secures all endpoints by default.

When it comes to complex applications we need different security policies per endpoints. We need to configure which endpoints should be secured, what type of users should be able to access the endpoints and endpoints that should be public.

A great example would be an endpoint which will displays a welcome message to the user.

package com.gkatzioura.security.securityendpoints.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {

    @GetMapping(path = "welcome")
    public String getMessage() {

        return "Welcome to the application";
    }
}

Regarding the fact that your application is already secured you need to provide public access to that endpoint.

In order to do so, spring provides us with the HttpSecurity class. By extending the WebSecurityConfigurerAdapter we can configure the endpoints which should be secured and the endpoint which should be public.

So let’s create the WebSecurityConfigurerAdapter configuration.

package com.gkatzioura.security.securityendpoints.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/welcome").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .permitAll()
            .and()
            .logout()
            .permitAll();
    }
}

So let’s take it to parts by calling the authorizeRequests function. We get an http configurer and it’s possible to add the endpoints that we want public or secure.
By calling the function antMatchers we can pass an array of ant patterns. The function applied would create a rule for each endpoint specified in the antmatchers.
The next function is the anyRequest. The authenticated rule will be apply to any request received.

Last but not least spring comes with the default login form and the default logout endpoint. In order to make it feasible to login and logout we must allow access to these endpoints.

So the end result would be to have the welcome endpoint publicly accessible, a preconfigured form for login and the logout endpoint.

Spring Security with Spring Boot 2.0: Password Encoder

On a previous post we used the user details service in order to provide a way to load our data from a function based on a username given.

The implementation of the user details might be backed by an in-memory mechanism, a sql/no-sql database etc.
The options are unlimited.

What we have to pay attention when it comes to password storage is the password hashing.
For security reasons we want to store passwords in a hashed form.
Supposing someone gets unauthorised access to the table storing our user data. By storing the passwords clear text that person can retrieve the password of every user in the system.

So we want a way to hash our passwords before storing them to database.
Always be aware that your hashing has to be robust and up to date.
For example MD5 was very popular in the past but nowadays leads to poor security. Actually it is possible to crack MD5 passwords fairly easy if you use a gpu.

Spring Security provides us with out of the box functionality when it comes to encoding passwords.
Password encoder is an interface which is used through the authorisation process.


package org.springframework.security.crypto.password;


public interface PasswordEncoder {

	String encode(CharSequence rawPassword);

	boolean matches(CharSequence rawPassword, String encodedPassword);

}

The encode function shall be used to encode your password and the matches function will check if your raw password matches the encoded password. Once your user details service fetches the user information from the database then the password given to authorise shall be validated with the one fetched from the database. In this case spring will use the matches function.

Now spring provides us with various implementations of a password encoder.
Let’s try to create a password encoder bean.

package com.gkatzioura.security.passwordencoder.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class PasswordEncoderConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new PasswordEncoder() {
            @Override
            public String encode(CharSequence rawPassword) {
                return rawPassword.toString();
            }

            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
                return rawPassword.toString().equals(encodedPassword);
            }
        };
    }
}

This bean is no different that the NoOpPasswordEncoder which comes with spring boot.
No we are going to do a small experiment and add a custom password encoder.
Our password encoder will compare the clear text password submitted by the user hash it and the compare it with an already hashed password from the equivalent user in our database.

To do the hashing we will user bcrypt.

    @Bean
    public PasswordEncoder customPasswordEncoder() {

        return new PasswordEncoder() {

            @Override
            public String encode(CharSequence rawPassword) {

                return BCrypt.hashpw(rawPassword.toString(), BCrypt.gensalt(4));
            }

            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {

                return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
            }
        };
    }

To test this we will set up our security by using the environmental variables as we’ve seen on a previous post.

First we need to have our password encoded. Our system will not have the password stored in any clear text form.

System.out.println(BCrypt.hashpw("user-password",BCrypt.gensalt(4)));
$2a$04$i4UWtMw6surai4dQMhoKSeLddi1XlAh2sSyG58K3ZvBHqVkhz8Y3y

So what we are gonna do next is to set our environmental variables before running our spring boot application.

SPRING_SECURITY_USER_NAME=test-user
SPRING_SECURITY_USER_PASSWORD=$2a$04$i4UWtMw6surai4dQMhoKSeLddi1XlAh2sSyG58K3ZvBHqVkhz8Y3y

Next step is to go to your login screen and give the credentials user-name and user-password.
As you can see you have just been authenticated.
Behind the scenes spring hashed the password you submitted and compared to the one existing through the environmental varialbles.

Spring Security with Spring Boot 2.0: UserDetailsService

As we have seen on a previous post the username and password for our spring application was configured through environmental variables. This is ok for prototype purposes however in real life scenarios we have to provide another way to make the users eligible to login to the application.
To do so we use the UserDetailsService Interface.

The user details service comes with the loadUserByUsername function. The loadUserByUsername locates the user based on the username. The result of the search if existing then validates the credentials given through the login form with the user information retrieved through the UserDetailsService.

So let’s start with a very simple custom user details service.

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        if(username.equals("test")) {

            return User.withDefaultPasswordEncoder()
                       .username("test")
                       .password("test")
                       .roles("test")
                       .build();
        } else {
            throw new UsernameNotFoundException();
        }
    }
}

As you can see the only user who is able to login is the one with the username test. Also spring provides us with a builder when it comes to user details. As a password encoder we have specified the default password encoder which is actually an encoder that does no password hashing at all since we provide the password clear-text.

Although the password encoder will be covered in another tutorial it is always good to remind that you should always hash the password stored in a database for security reasons.

Now do you need to add any extra information? Well no. Just having a bean that implements the UserDetailsService, in you spring context, is enough. Spring security will pick the UserDetailsService implementation you provided and this will be used to authenticate.

For example you can even provide the UserDetailsService by using the @Bean Configuration.

@Configuration
public class SecurityConfig {

    @Bean
    public UserDetailsService createUserDetailsService() {
        return new UserDetailsServiceImpl();
    }
    
}

By this way regardless where your store your user information whether it is on an sql database, a nosql-database or even a csv file the only thing that you have to do is in your loadUserByUsername to load the user and pass him back by creating a UserDetails object.

Spring Security with Spring Boot 2.0: Simple authentication using the Servlet Stack

Spring security is a great framework saving lots of time and effort from the developers. Also It is flexible enough to customize and bring it down to your needs. As spring evolves spring security involves too making it easier and more bootstrapping to setup up security in you project.

Spring Boot 2.0 is out there and we will take advantage of it for our security projects.

On this Project we aim at creating an as simple security backed project as possible. To get started we shall create a simple spring boot 2.0 project.

We can use the spring SPRING INITIALIZR application.

The end result of the project would be to have a spring boot 2 project with gradle.

buildscript {
	ext {
		springBootVersion = '2.0.1.RELEASE'
	}
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.gkatzioura.security'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
	mavenCentral()
}


dependencies {
	compile('org.springframework.boot:spring-boot-starter-security')
        compile('org.springframework.boot:spring-boot-starter-web')
	testCompile('org.springframework.boot:spring-boot-starter-test')
	testCompile('org.springframework.security:spring-security-test')
}

Now be aware that with Spring Boot 2 there are two stacks to go. Either the Servlet stack or the WebFlux reactive stack. On this tutorial we shall use the servlet stack. We will cover WebFlux on another tutorial.

Let’s go and add our first controller.

package com.gkatzioura.security.simple.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {

    @GetMapping("/hello")
    public ResponseEntity<String> hello(String name) {

        return new ResponseEntity<>("Hello "+name, HttpStatus.OK);
    }

}

If we try to access the endpoint http://localhost:8080/hello?name=john we will be presented with a login screen.
Thus including the security dependency in our project auto secures our endpoints and configures a user with a password.
In order to retrieve the password you can check at the login screen.
The username would be ‘user’ and the password will be the one that spring autogenerates.

Of course using an autogenerated password is not sufficient, thus we are going to provide the username and the password of our choice.

One of the ways to set your username and password on the application.yaml file

spring:
  security:
    user:
      name: test-user
      password: test-password

Now putting you passwords in the file system especially when not encrypted is not a good practice, let alone being uploaded in you version control since application.yaml is a source file. Also anyone with access to the binary can retrieve the username and password

Therefore instead of putting these sensitive information in the application.yaml file you can set them by using environmental variables.

So your environmental variables would be

SPRING_SECURITY_USER_NAME=test-user
SPRING_SECURITY_USER_PASSWORD=test-password

To sum up this was the easiest and fastest way to add security to your project.
On the next blog we will do the same but using the WebFlux reactive stack.

Spring boot and Apache Camel

As the world of software moves on, more complex systems are being developed, which have to integrate with each other. It started with SOA and it continues with microservices.

Camel is the number one integration tool that comes to my mind since nowadays spring boot with camel is a very strong combination.

 

Apache Camel

The first step is to include the camel dependencies to our spring project.

buildscript {
	ext {
		springBootVersion = '1.5.9.BUILD-SNAPSHOT'
	}
	repositories {
		mavenCentral()
		maven { url "https://repo.spring.io/snapshot" }
		maven { url "https://repo.spring.io/milestone" }
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

group = 'com.gkatzioura'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
	mavenCentral()
	maven { url "https://repo.spring.io/snapshot" }
	maven { url "https://repo.spring.io/milestone" }
}


dependencies {
	compile('org.apache.camel:camel-spring-boot-starter:2.20.0')
	testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.apache.camel:camel-test-spring:2.20.0')
}

In order to have a faster project setup from scratch you can always use the online spring initializer.

Now let’s add a simple route

package com.gkatzioura.springcamel.routes;

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

@Component
public class TimerRoute extends RouteBuilder {

    public static final String ROUTE_NAME = "TIMER_ROUTE";

    @Override
    public void configure() throws Exception {
        from("timer:initial//start?period=10000")
                .routeId(ROUTE_NAME)
                .to("log:executed");
    }
}

We don’t have to worry about the camel context configuration since the Camel auto-configuration creates a SpringCamelContext for you and takes care of the proper initialization and shutdown of that context.

Also camel auto-configuration collects all the RouteBuilder instances from the Spring context and automatically injects them into the provided CamelContext. Thus we don’t have to register our routes to the CamelContext.

As you can see our route has a timer with a period of 10000 milliseconds which routes to a log endpoint. The log endpoint will print the executed string every 10000 milliseconds.

Keep in mind that if no routeId is specified, camel will assign a name on its own, therefore giving a name to our route definition is a good practice in case we want to retrieve the root definition.

In order for camel to stay up, we need to keep our main thread blocked. Thus we add this configuration to our application.yml file.

camel:
  springboot:
    main-run-controller: true

Instead of this we can include the spring-boot-starter-web dependency, but our application has as few dependencies as possible, and we need to keep it this way.

However the most difficult part in the integration with other systems is testing. Throughout the years there have been rapid advancements on testing and the tools that we use.
Camel also comes packaged with some great tools in order to unit test.

For example we will implement a test of the route specified previously.

@RunWith(CamelSpringBootRunner.class)
@SpringBootTest
public class SpringCamelApplicationTests {

    @EndpointInject(uri = MOCK_RESULT)
    private MockEndpoint resultEndpoint;

    @Autowired
    private CamelContext camelContext;

    @EndpointInject(uri = MOCK_TIMER)
    private ProducerTemplate producer;

    private static final String MOCK_RESULT = "mock:result";
    private static final String MOCK_TIMER = "direct:mock-timer";

    @Before
	public void setup() throws Exception {

	    camelContext.getRouteDefinition(TimerRoute.ROUTE_NAME)
                .autoStartup(true)
                .adviceWith(camelContext, new AdviceWithRouteBuilder() {
                    @Override
                    public void configure() throws Exception {
                        replaceFromWith(MOCK_TIMER);
                        interceptSendToEndpoint("log*")
                                .skipSendToOriginalEndpoint()
                                .to(MOCK_RESULT);
                    }
                });
    }

    @Test
    public void sendMessage() throws Exception {

        resultEndpoint.expectedMessageCount(1);
        producer.sendBody("A message");
        resultEndpoint.assertIsSatisfied();
    }

}

Let’s have a look on each part of the test.

Our JUnit runner of choice would be the CamelSpringBootRunner.class

@RunWith(CamelSpringBootRunner.class)

We inject a ProducerTemplate. The ProducerTemplate interface allows you to send message exchanges to endpoints in a variety of different ways to make it easy to work with Camel Endpoint instances from Java code.

Then we inject a MockEndpoint. The MockEndpoint will serve us by replacing the original endpoint. Then we will set the expected number of messages to be received. Once the processing is done we assert that the amount of received messages is satisfied.

On our setup method we will replace our original endpoint with the fake producer template endpoint. Thus our route will receive the events that we will issue from the ProducerTemplate.
Then we will also intercept the log endpoint and direct the message to the MockEndpoint previously specified.

So we ended up withe a camel application and a unit test for the route specified.
You can find the source code on github.

Spring and Threads: Transactions

In order to be able to use transactions with our thread we need to understand how transactions work with spring. Transaction information in spring is stored in ThreadLocal variables. Therefore these variables are specific for an ongoing transaction on a single thread.

icon-spring-framework

When it comes to an action run by a single thread the transaction gets propagated among the spring components called hierarchically.

Thus in case of a @Transactional  annotated service which spawns a thread, the transaction will not be propagated from the @Transactional service to the newly created thread. The result will be an error indicating that the transaction is missing.

Since the action that take place inside your thread, requires database access through jpa, a new transaction has to be created.

By looking at the @Transactional documentation  we can get more information on the transaction propagation types. The default propagation mode for @Transactional is REQUIRED.

Therefore by annotating a method with the @Transactional, a new transaction will be created and will be propagated to the other services called from our thread.

For example our async method can be annotated as Transactional


@Async
@Transactional
public void executeTransactionally() {
    System.out.println("Execute a transaction from the new thread");
}

The same applies for the method which will be invoked from the run function of a Runnable class. Although async is pretty simple to use, behind the scenes it wraps the call in a Runnable, which dispatched to an executor.

To sum up when it comes to work with threads and transaction in spring, it should be done with extra care. Also keep in mind that the transactions cannot be passed from thread to thread. Last but not least make sure that your @Async and @Transactional functions are public and go though the proxy that will make the necessary actions before being invoked.

Last but not least I’ve compiled a cheat sheet that lists some helpful spring & threads tips.
Sign up in the link to receive it.

Spring and Threads: Async

Previously we started working with spring and the TaskExecutor, thus we became more familiar on how to use threads on a spring application.

However using the task executor might be cumbersome especially when we need to execute a simple action.

Spring’s Asynchronous methods come to the rescue.

Instead of messing with runnables and the TaskExecutor, you trade the control of the executor for the simplicity of the async functions.
In order to execute your function in another thread all you have to do is to annotate your functions with the @Async annotation.

Asynchronous methods come with two modes.

A fire and forget mode: a method which returns a void type.

    @Async
    @Transactional
    public void printEmployees() {

        List<Employee> employees = entityManager.createQuery("SELECT e FROM Employee e").getResultList();
        employees.stream().forEach(e->System.out.println(e.getEmail()));
    }

A results retrieval mode: a method which returns a future type.

    @Async
    @Transactional
    public CompletableFuture<List<Employee>> fetchEmployess() {
        List<Employee> employees = entityManager.createQuery("SELECT e FROM Employee e").getResultList();
        return CompletableFuture.completedFuture(employees);
    }

Pay extra attention to the fact that @Async annotations do not work if they are invoked by ‘this’. @Async behaves just like the @Transactional annotation. Therefore you need to have your async functions as public. You can find more information on the aop proxies documentation.

However using only the @Async annotation is not enough. We need to enable Spring’s asynchronous method execution capability by using the @EnableAsync annotation in one of our configuration classes.

package com.gkatzioura.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

/**
 * Created by gkatzioura on 4/26/17.
 */
@Configuration
@EnableAsync
public class ThreadConfig {

    @Bean
    public TaskExecutor threadPoolTaskExecutor() {

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(4);
        executor.setMaxPoolSize(4);
        executor.setThreadNamePrefix("sgfgd");
        executor.initialize();

        return executor;
    }

}

The next question is how we declare the resources and the threads pools that the async functions will use. We can get the answer from the documentation.

By default, Spring will be searching for an associated thread pool definition: either a unique TaskExecutor bean in the context, or an Executor bean named “taskExecutor” otherwise. If neither of the two is resolvable, a SimpleAsyncTaskExecutor will be used to process async method invocations.

However in some cases we don’t want the same thread pool to run all of application’s tasks. We might want separate threads pools with different configurations backing our functions.

To achieve so we pass to the @Async annotation the name of the executor we might want to use for each function.

For example  an executor with the name ‘specificTaskExecutor’ is configured.

@Configuration
@EnableAsync
public class ThreadConfig {

    @Bean(name = "specificTaskExecutor")
    public TaskExecutor specificTaskExecutor() {

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.initialize();
        return executor;
    }

}

Then our function should set the qualifier value to determine the target executor of a specific Executor or TaskExecutor.

@Async("specificTaskExecutor")
public void runFromAnotherThreadPool() {
    System.out.println("You function code here");
}

On the next article we will talk about transactions on threads.

You can find the sourcecode on github.

Last but not least I’ve compiled a cheat sheet that lists some helpful spring & threads tips.
Sign up in the link to receive it.

Spring and Threads: TaskExecutor

Using threads in a web application is not unusual especially when you have to develop long running tasks.

Considering spring we must pay extra attention and use the tools it already provides, instead of spawning our own threads.
We want our threads to be managed by spring and thus be able to use the other components of our application without any repercussions, and shutdown our application gracefully without any work being in progress.

Spring provides the TaskExecutor as an abstraction for dealing with executors.
The Spring’s TaskExecutor interface is identical to the java.util.concurrent.Executor interface.
There are a number of pre-built implementations of TaskExecutor included with the Spring distribution, you can find more about them from the official documentation.
By providing to your spring environment a TaskExecutor implementation you will be able to inject the TaskExecutor to your beans and have access to managed threads.

package com.gkatzioura.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import java.util.List;

/**
 * Created by gkatzioura on 4/26/17.
 */
@Service
public class AsynchronousService {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private TaskExecutor taskExecutor;

    public void executeAsynchronously() {

        taskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                //TODO add long running task
            }
        });
    }
}

First step is to add the TaskExecutor configuration to our spring application.

package com.gkatzioura.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

/**
 * Created by gkatzioura on 4/26/17.
 */
@Configuration
public class ThreadConfig {

    @Bean
    public TaskExecutor threadPoolTaskExecutor() {

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(4);
        executor.setMaxPoolSize(4);
        executor.setThreadNamePrefix("default_task_executor_thread");
        executor.initialize();

        return executor;
    }

}

Once we have our executor setup the process is simple. We inject the executor to a spring component and then we submit Runnable classes containing the tasks to be executed.

Since our asynchronous code might as well need to interact with other components of our application and have them injected, a nice approach is to create prototype scoped runnable instances.

package com.gkatzioura;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * Created by gkatzioura on 10/18/17.
 */
@Component
@Scope("prototype")
public class MyThread implements Runnable {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyThread.class);

    @Override
    public void run() {
        
        LOGGER.info("Called from thread");
    }
}

Then we are ready to inject the executor to our services and use it to execute runnable instances.

package com.gkatzioura.service;

import com.gkatzioura.MyThread;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by gkatzioura on 4/26/17.
 */
@Service
public class AsynchronousService {

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private ApplicationContext applicationContext;

    public void executeAsynchronously() {

        MyThread myThread = applicationContext.getBean(MyThread.class);
        taskExecutor.execute(myThread);
    }

}

On the next article we will bring our multit-hreaded codebase to a new level by using spring’s asynchronous functions.

You can find the sourcecode on github.

Last but not least I’ve compiled a cheat sheet that lists some helpful spring & threads tips.
Sign up in the link to receive it.

Spring Data with JPA and @NamedQueries

If you use Spring Data and @NamedQuery annotations at your JPA entity you can easily use them in a more convenient way using the spring data repository.

On a previous blog we created a spring data project using spring boot and docker. We will use the pretty same project and enhance our repository’s functionality.

We will implement a named query that will fetch employees only if their Last Name has as many characters as the ones specified.

package com.gkatzioura.springdata.jpa.persistence.entity;

import javax.persistence.*;

/**
 * Created by gkatzioura on 6/2/16.
 */
@Entity
@Table(name = "employee", schema="spring_data_jpa_example")
@NamedQuery(name = "Employee.fetchByLastNameLength",
        query = "SELECT e FROM Employee e WHERE CHAR_LENGTH(e.lastname) =:length "
)
public class Employee {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    @Column(name = "firstname")
    private String firstName;

    @Column(name = "lastname")
    private String lastname;

    @Column(name = "email")
    private String email;

    @Column(name = "age")
    private Integer age;

    @Column(name = "salary")
    private Integer salary;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getSalary() {
        return salary;
    }

    public void setSalary(Integer salary) {
        this.salary = salary;
    }
}

Pay extra attention to the query name and the convention we follow @{EntityName}.{queryName}.
Then we will add the method to our spring data repository.

package com.gkatzioura.springdata.jpa.persistence.repository;

import com.gkatzioura.springdata.jpa.persistence.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * Created by gkatzioura on 6/2/16.
 */
@Repository
public interface EmployeeRepository extends JpaRepository<Employee,Long>, EmployeeRepositoryCustom {

    List<Employee> fetchByLastNameLength(@Param("length") Long length);
}

And last but not least add some functionality to our controller.

package com.gkatzioura.springdata.jpa.controller;

import com.gkatzioura.springdata.jpa.persistence.entity.Employee;
import com.gkatzioura.springdata.jpa.persistence.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * Created by gkatzioura on 6/2/16.
 */
@RestController
public class TestController {

    @Autowired
    private EmployeeRepository employeeRepository;

    @RequestMapping("/employee")
    public List<Employee> getTest() {

        return employeeRepository.findAll();
    }

    @RequestMapping("/employee/filter")
    public List<Employee> getFiltered(String firstName,@RequestParam(defaultValue = "0") Double bonusAmount) {

        return employeeRepository.getFirstNamesLikeAndBonusBigger(firstName,bonusAmount);
    }

    @RequestMapping("/employee/lastnameLength")
    public List<Employee> fetchByLength(Long length) {
        return employeeRepository.fetchByLastNameLength(length);
    }

}

You can find the source code on github.

Hibernate Caching with HazelCast: Basic configuration

Previously we went through an introduction on JPA caching, the mechanisms and what hibernate offers.

What comes next is a hibernate project using Hazelcast as a second level cache.

We will use a basic spring boot project for this purpose with JPA. Spring boot uses hibernate as the default JPA provider.
Our setup will be pretty close to the one of a previous post.
We will use postgresql with docker for our sql database.

group 'com.gkatzioura'
version '1.0-SNAPSHOT'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.1.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

repositories {
    mavenCentral()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
    compile group: 'org.postgresql', name:'postgresql', version:'9.4-1206-jdbc42'
    compile group: 'org.springframework', name: 'spring-jdbc'
    compile group: 'com.zaxxer', name: 'HikariCP', version: '2.6.0'
    compile group: 'com.hazelcast', name: 'hazelcast-hibernate5', version: '1.2'
    compile group: 'com.hazelcast', name: 'hazelcast', version: '3.7.5'
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

By examining the dependencies carefully we see the hikari pool, the postgresql driver, spring data jpa and of course hazelcast.

Instead of creating the database manually we will automate it by utilizing the database initialization feature of Spring boot.

We shall create a file called schema.sql under the resources folder.

create schema spring_data_jpa_example;

create table spring_data_jpa_example.employee(
    id  SERIAL PRIMARY KEY,
    firstname   TEXT    NOT NULL,
    lastname    TEXT    NOT NULL,
    email       TEXT    not null,
    age         INT     NOT NULL,
    salary         real,
    unique(email)
);

insert into spring_data_jpa_example.employee (firstname,lastname,email,age,salary)
values ('Test','Me','test@me.com',18,3000.23);

To keep it simple and avoid any further configurations we shall put the configurations for datasource, jpa and caching inside the application.yml file.

spring:
  datasource:
    continue-on-error: true
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:postgresql://172.17.0.2:5432/postgres
    driver-class-name: org.postgresql.Driver
    username: postgres
    password: postgres
    hikari:
      idle-timeout: 10000
  jpa:
    properties:
      hibernate:
        cache:
          use_second_level_cache: true
          use_query_cache: true
          region:
            factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
    show-sql: true

The configuration spring.datasource.continue-on-error is crucial since once the application relaunches, there should be a second attempt to create the database and thus a crash is inevitable.

Any hibernate specific properties reside at the spring.jpa.properties path. We enabled the second level cache and the query cache.

Also we set show-sql to true. This means that once a query hits the database it shall be logged through the console.

Then create our employee entity.

package com.gkatzioura.hibernate.enitites;

import javax.persistence.*;

import java.io.Serializable;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

/**
 * Created by gkatzioura on 2/6/17.
 */
@Entity
@Table(name = "employee", schema="spring_data_jpa_example")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee implements Serializable {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    @Column(name = "firstname")
    private String firstName;

    @Column(name = "lastname")
    private String lastname;

    @Column(name = "email")
    private String email;

    @Column(name = "age")
    private Integer age;

    @Column(name = "salary")
    private Integer salary;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getSalary() {
        return salary;
    }

    public void setSalary(Integer salary) {
        this.salary = salary;
    }
}

Everything is setup. Spring boot will detect the entity and create an EntityManagerFactory on its own.
What comes next is the repository class for employee.

package com.gkatzioura.hibernate.repository;

import com.gkatzioura.hibernate.enitites.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;

/**
 * Created by gkatzioura on 2/11/17.
 */
public interface EmployeeRepository extends JpaRepository {
}

And the last one is the controller

package com.gkatzioura.hibernate.controller;

import com.gkatzioura.hibernate.enitites.Employee;
import com.gkatzioura.hibernate.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * Created by gkatzioura on 2/6/17.
 */
@RestController
public class EmployeeController {

    @Autowired
    private EmployeeRepository employeeRepository;

    @RequestMapping("/employee")
    public List testIt() {

        return employeeRepository.findAll();
    }

    @RequestMapping("/employee/{employeeId}")
    public Employee getEmployee(@PathVariable Long employeeId) {

        return employeeRepository.findOne(employeeId);
    }

}

Once we issue a request at
http://localhost:8080/employee/1

Console will display the query issued at the database

Hibernate: select employee0_.id as id1_0_0_, employee0_.age as age2_0_0_, employee0_.email as email3_0_0_, employee0_.firstname as firstnam4_0_0_, employee0_.lastname as lastname5_0_0_, employee0_.salary as salary6_0_0_ from spring_data_jpa_example.employee employee0_ where employee0_.id=?

The second time we issue the request, since we have the second cache enabled there won’t be a query issued upon the database. Instead the entity shall be fetched from the second level cache.

You can download the project from github.