Spring Cloud with Spring Config and Eureka in high availability using docker swarm

Spring Cloud and Netflix stack is awesome, it is easy to setup by using several annotations everything just snaps into place. All of the microservices patterns like auto discovery, centralized configuration, centralized logging , autoscaling are solved and ready to be used.

In this post I will show you how to use this tools and deploy them to your docker swarm in a highly available way. First I will show you how to have Eureka in a high available way using two instances that talk to each other. Then I will show you how to have Spring Remote Config scaled to 3 instances and of course client app that talks with Eureka and Spring config is gong to be scaled to 3 as well. Docker swarm is going to be deployed to 3 virtual machines.

Before we start let me turn your attention to some other posts that you might read before you jump into serious stuff ūüôā

In the previous post I wrote about Spring Remote Config  and shown how to leverage different profiles of spring config like native, git and vault. Then some time ago I wrote about docker swarm that is deployed to 3 machines and have scaled nginx.

Spring Remote Config

In this example I wanted to setup remote config that loads configuration from my GitHub account . You can check the configurations out is is fairly simple.   To set this up I have created one spring boot app using next dependencies :

First is important so that we can have config server and other is so that we can protect it and restrict access in a easy way. ( you should however use better security mechanism for your production system but for a demonstration this is secure enough).

Main Class of the spring boot is really simple, it just has @EnableConfigServce annotation that creates all the magic.

There is one application.properties file with few basic properties like application name, basic auth user name and password, along with profile and url to my GitHub repository.

I will explain all of the files located in this repository latter.

Eureka Server

As you probably know Eureka server acts as a registry and allows all clients to register them selves and be able to find ip address and port of other services if they want to talk to. Eureka server is a client as well. This property is used to setup Eureka in highly available way.

Dependencies for the Eureka Server are:

Config starter is required because Eureka loads all configuration from the remote config, and security is here so that we can restrict access.

Spring Boot main class is simpleit just has @EnableEurekaServer annotation that creates all the magic.

We are going to have Eureka deployed in a highly available way ( using two Eureka instances, we can have more if we want to using same pattern). First instance is going to have name eureka and second is going to be called eureka-backup so that we easily understand who is who in the docker swarm and that two eureka instances can talk to each other. Both instances are going to have their own configurations.

eureka.properties

eureka-backup.properties

Observe that both instances have same username and password, ports are different and both instances know how to talk to each other because serviceUrl points to the other instance with username and password written into the URL. This is all it takes to setup eureka into highly available way.

I have disabled selfPreservation, here is a good explanation of how this works here.

How is eureka going to know where is config server located ?

For this we have bootstrap.properties file with next content:

http://config:8888 is the address of the config service that runs in the docker swarm in the same network.

Spring Boot Client

In this example we are going to have one client, in a real case we can have 100 or even more small microservices that use remote config server to load configuration from, but the principal is the same.

Client is going to be a simple web application with next dependencies:

We need actuator so that we can execute http POST request to /refresh and refresh the configuration.

We need config so that application can load the configuration from remote configuration server.

We need eureka to register the client.

Finally we need web so that app can be web application :).

Spring boot main class is :

There are few annotations

  • @RefreshScope, used to tell spring to refresh the bean instance when we hit /refresh mentioned above so that property response is refreshed
  • @EnableEurekaClient, used to enable eureka client and register the app to eureka server.

You can find all of the code HERE on my git hub account.

In the next section I show you how to

  • dockerize apps
  • prepare docker swarm using 3 virtual machines
  • build docker images
  • spin up images into containers with initial scaling
  • and show you how to manage docker swarm using portainer.io as a client.

App Dockerization

What I want is to deploy this three applications to docker swarm, to make this possible I need to create docker image out of every project.

Creating docker image from a spring boot project is a fairly simple task using a maven plugin that is added into the pom.xml.

Additionally you need to add property docker.image.prefix

Plugin will create an image named springio/eureka for example. Optionally you can push the image into the image repository.

Docker image can not be created without a blueprint. Instructions on how to build an image are located in file Dockerfile located on path /src/main/docker/Dockerfile . Here is the content of the standard Dockerfile.

Observe the third line ADD config-0.0.1-SNAPSHOT.jar app.jar , this line adds the self executable jar file into the docker image. It is important to notice that you need to set jar name properly in order to make it work.

You can alter the command to work with any name of the jar.

Once we have project setuped all that is left is to execute the command and create an image:

If you run this in all of your projects you will have 3 images created for you. Here is a handy script for you to make this work. Go to the root of the project and execute:

Execute docker images ls to verify.

This is the end of the dockerization of the images, in next section I will create docker swarm and start those apps.

Docker Swarm

To get started with docker swarm I advise that you read the post , this will help you get going with docker swarm using docker-machine. There I have used macOS to set all up.

Here I will just list the commands that will

  • create three docker-machines
  • initialize swarm with manager
  • join two workers machines
  • start 4 services and setup scaling for each service
Create docker machines

First I will create 3 docker machines using names manager, worker1 and worker2. Their name will represent their role in the swarm.

To validate that docker machines are created execute next command

Pay attention to the ip of the manager as you will need to know the address in the next section.

Initialize swarm

To initialize swarm properly you should have advertise-addr set as the manager IP address.

Create Network for docker

What we want is to allow containers to reference each other using their names. To make this happen I will create one network using overlay driver using next command:

Docker Services

Creating docker swarm is not enough we need to tell docker what services are going to be executed in the swarm. To create a services we need a number of parameters :

  • number of replicas
  • name of the service
  • reserve-memory
  • published ports
  • update-delay
  • network
  • image

Now lets create all required services.

Config Service

Eureka and Eureka-backup service

Observe that both services are using same image springio/eureka but different application name is being passed to the service. This allows gives us good leverage to use one image and have multiple configurations for each of the Eureka instances.

Client Service

Monitoring docker swarm

We need a way to monitor and manage a docker swarm, for this Portainer is used. To create a portainer service use :

Visit the url http://192.168.99.102:9000/ , setup the initial password and you are ready to go.

What did we do so far?

First we have created a 3 maven projects for

  • Eureka
  • Spring config, with git reporitory
  • Client app

Then we have built all of the apps creating 3 images and have prepared the docker swarm. In docker swarm we have created 4 services , two for eureka so that we have high availability, one for spring config and client.

After we have started all of the containers we opened the portainer to mange the docker swarm. Here we can manage secrets, view nodes and update services among other things.

Where to go next?

There are number of things you can do, first you can use docker secrets to pass the username and password of the config server. You can also use some other authentication mechanism for your apps…

In order to build an application with high number of microservices auto refreshing the configurations is a must. For this you will need to add spring cloud bus and rabbitMQ…

Related GitHub repository :

https://github.com/savicprvoslav/spring-cloud-config-eureka-docker

 

 

Spring Cloud remote config tutorial

Introduction

In the big applications where there are multiple moving parts ( microservices ) there is a problem of configuration management. Microservices must be disposable applications that can be started and killed frequently, so would it just be awesome to hold configuration at one place and allow microservices to obtain the configuration from this single location.

We can easily manage all configurations on one place and all that is required for the microservices is to know what is the profile it is running in, for example PRODUCTION, STAGE …

In this post I will cover the Spring Cloud Remote Config using three config sources

  1. Native, where configuration is stored on the hard drive
  2. Git, where configuration is stored in git repository
  3. Vault, this is my favorite all secrets are stored in vault
Setting the project

To get things started first we need to create two applications:

  • Config Server
  • Client

Config server serves the configuration to the clients and has REST API that is used by the client apps that want to obtain configurations.

To get things started here is the pom.xml I used to create config server for brevity I removed all unimportant parts of it.

Because this is Spring Boot application we need Application class that is annotated with @EnableConfigServer and @SpringBootApplication.

@EnableConfigServer is very powerful annotation as it is all that it takes to have config server running.

If you run ConfigServerApplication you will not get far because you will get error stating:

You need to configure a uri for the git repository

This is because config server default profile is git and we did not specify the config server profiles and configuration yet. So lets create one application.properties file and add next lines of code that will specify port, config name and profiles. For now we will have only native profile and latter we will add git and vault here as well.

Spring Cloud Config native profile

What is native profile?

Native profile allows that configuration files are located on the hard drive of the server. Not very good for production but is awesome as a starting point.

We are going to have one application that feeds the configuration from config server and it is going to have most awesome name ever configclient. It is important to memorize app name as it will be important in the next paragraph.

We can split configuration into two separate parts for each application:

  • Default configuration
  • Configuration for specific profile

Default configuration will go in the file configclient.properties  or {APPLICATION_NAME}.yml and settings for specific profile ( in our case production) will to go into configclient-production.yml or configclient-{PROFILE}.yml. All the files can be located in location specified by configuration  ( you may investigate the class NativeEnvironmentRepository to see all the default locations):

configclient.yml:

configclient-production.yml

As you can see here configuration for production and for default overlap in rs.pscode.value .

Now if you start the config server application and hit the URL  localhost:8888/configclient/default response is

and if you hit the  localhost:8888/configclient/production

response will be :

Awesome, this was easy. Lets move on to git profile.

Spring Cloud Config git profile

In previous section we enabled native profile and now we will enable git profile, to do this we need to add git to the profile list :

Remember you do not need to leave native if you do not want to.

Next we need to specify the git repository url with username and password if required like so.

You will notice that search-paths is used , this is because configuration is not located in the root of the project it is located in config folder.

There are numerous options for git, like multiple repositories and so on … ¬†you can check this out in the reference and looking at the implementation of EnvironmentRepository for git¬† MultipleJGitEnvironmentRepository¬†.

You may wonder because there are two profiles native and git who will win ? Well last specified profile will override previously specified.

Spring Cloud Config Vault

What about those configurations that are supposed to be secrets, you know things that only few know? We can not put those in the git repository or store them on the hard drive of the server, well no.

For this problem spring vault comes to rescue, make sure to check the vaults website https://www.vaultproject.io/ and their get started pages.

This part of the post is going to require some docker knowledge, but nothing big. First we are going to create two containers vault and vault-ui , then we will add two secrets in vault and configure our config application to point to vault server.

Step 1: Create vault container.

I did specify the root token here, do not do that in production.

Step 2: Enter the vault container

Step 3: Authenticate to vault and configure the vault client properly

If you see the logs of the started container you will see something like:

So as it says we need to enter the container using

then execute ( observe myroot is used as token specified when container is started)

Step 3: Save some secrets

You should have two response Success! messages like this

so the secret names are composed of secret/{ApplicationName}-{profile}.

Step 4: Configure the config server to talk to Vault

In the application.properties add and append( or just set) profiles with vault

Step 5: Get URL  localhost:8888/configclient

And it does not work  it shows the error :

What the hell is this you may ask , well the client must provide with especial header

X-Config-Token with value myroot .

 

Vault-ui is a really nice application that allows you to manage vault using great UI. Find the page of vault-ui on docker hub and start it ( https://hub.docker.com/r/djenriquez/vault-ui/)

Then open the page and enter the url of the vault server. Here you may have multiple docker configurations, so if you have docker for mac you can :

1: Obtain the ip of the host computer by entering the vault

and executing

Then in the vault-ui enter the IP address printed by the upper command like so:

and enter the token myroot to see this

As you see in the image are the secrets we entered using console.

Spring Cloud Config Client Part

Now when we know how to setup config server we need to use the values using the client application. Here is the ConfigClientApplication main class. It is really simple except it has @RefreshScope annotation.

Configuration is loaded on application startup and if we update any of the configurations in our config server client application will now know. This is where @RefreshScope comes handy, it marks the beans that are refreshed once /refresh REST API is called. Awesome right?

Here is the important part of the pom.xml for the client app

If you read the spring cloud reference you will notice that there are two contexts application and bootstrap context as a parent of the previous one. This means that configuration related to config server has to be put in bootstrap.properties for the bootstrap phase …

  • spring.application.name is the name of the application that maps to config file names
  • spring.cloud.config.uri is the url to the config server
  • spring.cloud.config.token is the vault token, remember the Missing required header: X-Config-Token
  • management.security.enabled , I skipped security
  • spring.profiles.include, current profile configuration

Now for the closing words lets call the localhost:8080/test . And here it is one value from vault, one from git.

 

Please do find the code on my git hub repository here:

https://github.com/savicprvoslav/Spring-Cloud-Config

 

 

 

 

Swagger Code Gen Retrofit2 library

Generating code using swagger-codegen is an easy way to get your client up and running using different languages and libraries. In this tutorial I will show how to create clients in java using retrofit2 library.

Basics

First you need to download swagger-codegen library to your computer using next command. You might want to recheck the current version in the github swagger-codegen repository here.

Next you want to execute command for generating the code. Here there are several mandatory parameters you need to add:

  • url to the api-docs
  • target language
  • library to be used
  • api and model package
  • output folder

java -jar swagger.jar generate -i http://localhost:8080/v2/api-docs ¬†-l java –library=retrofit2 -DmodelPackage=rs.pscode.start.model,apiPackage=rs.pscode.start.api -o spring-boot-starter-genereated

Retrofit2

Generating retrofit 2 client code can be done using next command

Here we have all necessary parameters like URL to the api-docs, language, library, packages and output folder.

 

 

Spring boot conditionals

Spring boot allows you to create components conditionally, ¬†already seen condition is¬†profile condition. You can just say @Profile(“dev”) and have different implementation of the bean.

What if you want to configure some especial condition, like enable or disable a feature? Here the @Conditional comes to play.

We want to create a service only if feature is configured to be enabled. Enabled status of the feature is specified using especial property in application.properties

To accomplish this we need to do 3 things

  1. Create Condition Implementation
  2. Create Condition Annotation
  3. Annotate the Class

 

Condition implementation is super simple, you just implement Condition interface and return true or false. Here I check if property is set to true.

Custom annotation that is annotated by especial annotation @Conditional with value set to condition implementation

Using FirebaseCondition I annotate my service that depends on this condition

This is it! Now FirebaseService will be wired only when application.property is correctly filled.

Firebase and Spring boot integration

Firebase can be integrated into the backend so that clients that are authenticated with firebase can call backend REST APIs.

To accomplish this few key parts must be added to the backend

  1. Maven Dependencies
  2. Filter
  3. Authentication provider
  4. Token parsing
  5. Registration

GitHub repository is here.

To add firebase dependencies one library must be added

Every request to the backend must have especial header that is used by FirebaseFilter. Filter checks if header named “X-Authorization-Firebase” exists, if does not this means that request should not be processed by this filter. When token is found it is parsed using firebaseService.parseToken(xAuth) and correct Authentication is created FirebaseAuthenticationToken that is put in the securityContextHolder. Job of the filter is here done and authentication process is being taken over by authentication provider.

Authentication provider uses the FirebaseAuthenticationToken to map the token to database user and set its roles.

Firebase backend configuration is done in one Configuration class. Here I have added firebase reference bean and initialization.

Initialization of firebase depends of two properties , configuration path and database url.

This is it. Be sure to checkout the GitHub repository here.

https://github.com/savicprvoslav/Spring-Boot-starter

 

Spring boot starter repository

Intro

Spring boot makes it easy to get started but putting together features like security, jpa, spring-data, user authentication on both mysql and embedded database , roles and profiles can sometimes take your time away. Main goal is to help start creating backend application to be used as REST API for multiple client applications, like android, iOS , angular and other clients.

GitHub

Included spring boot starters

There are several included spring boot starters

  • spring-boot-starter-web
  • spring-boot-starter-data-jpa
  • spring-boot-starter-security
  • spring-boot-starter-actuator
  • spring-boot-devtools

Additional libraries used are

  • mysql-connector-java
  • hsqldb
  • org.modelmapper.modelmapper

Web

As a example one resource is created and named TestResource that demonstrates how to

  • use @RestController
  • inject services
  • map methods to URLs
  • inject configurational properties
  • specify the http status values

Exception Handler annotated with @ControllerAdvice is added to handle exceptions with custom response.

For generating the output for client applications modelmapper is used. It converts for example TestEntity to TestJson. Here is the word or two from official website http://modelmapper.org:

“Why ModelMapper? The goal of ModelMapper is to make object mapping easy, by automatically determining how one object model maps to another, based on conventions, in the same way that a human would – while providing a simple, refactoring-safe API for handling specific use cases.”

Using modelMapper is super easy to use, here is how to convert List to List.

REST api is split into 3 big sections

  • /api/open
  • /api/client
  • /api/admin

Each of the sections is secured so that users with correct roles can use them

JPA

All of the data means nothing if it can not be persisted, for this problem JPA is used with JpaRepositories enabled. This allows you to quickly create DAO layer. Initially only one entitiy is created the TestEntity, it is super simple with just generated ID of the entity.

Spring JpaRepositories are awesome way for creating DAO layer quick and easy, here is how to create JpaRepository for TestEntity that has CRUD abilities.

To utilize the repository all you need to do is inject it

Additionally two more entities are used UserEntity and RoleEntity, so that spring security can be setuped and users are allowed to login.

Transactions are enabled by default so now you can add @Transactional annotations freely

Spring Security

Securing the data is important, for this important task spring security is used. Initially there are 3 roles in the system

  • Admin Role
  • User Role
  • Anonymous Role

REST API is secured so that

  • Administrators can call only /api/admin
  • Users can call only /api/client
  • Anonymous users can call only /api/open

Method security is enabled with @EnableGlobalMethodSecurity(securedEnabled = true), this means that you can protect your service layer by annotating the public methods like this

Users are authenticated against the database, to setup this service UserService is created, here is the relevant part of the setup where user details service is set to the AuthenticationManagerBuilder.

In the dao layer two entities are created as mentioned above UserEntity and RoleEntity

All that remains is to query the database and load the user and prefill the roles if user has some

Spring actuator

Actuator is an interesting part of the app, it allows administrators to use REST api and test if the backend is working and what is the status of it. Here are some examples

To demonstrate how to create custom health indicator there is PomodoroHealthIndicator as a demonstration.

Spring actuator allows you to monitor the application by creating counts. In the TestService every time when Pomodoro is created counter service is called like this

Now when we call /metrics we can see how many pomodors are created.

Devtools

Devtools can help you develop, one feature is currently used directly so that you do not need to stop start the app all the time during development
spring.devtools.restart.enabled=true

Profiles

There are two profiles that are enabled in the system

  • prod
  • dev

For each profile application-{env}.properties file is created. In each file you can add your properties that depend of the profile that is enabled. Enabling profile is done in the applicatin.properties file

application-prod.properties has mysql access specified but application-dev.properties has no mysql access specified, this is a nice way to tell spring to use embedded database for dev environment. Here is the application-prop.properties, this tells spring boot that we want to have datasource that connects to mysql.

Swagger 2

Swagger 2 is used to allow developers to view your REST API is a simple and understandable way.

Maven dependencies:

 

Enabled only in ‘dev’ profile.

Because of swagger especial configuration is added in spring security section and WebSecurityConfigurerAdapter

Swagger UI is accessible on http://localhost:8080/swagger-ui.html

 

GitHub Repository

Spring boot Configuration properties

Spring boot is awesome and it allows you to configure your app using external properties file (application.properties) with no problem at all. Here is the example of the application.property file located in the class path.

Injecting myValue is super easy, it can be done using @Value annotation like this

Same would go for other awesomeConfiguration values and here is the problem. We have a number of items that all belong to the group awesomeConfiguration it would be great if we could load all the values into the spring bean. Configuration properties to the rescue!

ConfigurationProperties

Configuration properties is set using 3 steps

1: Create POJO object where all property values are going to be loaded and specify @ConfigurationProperties with prefix to control what values are used.

2: enable Configuration properties in your spring config class using annotation @EnableConfigurationProperties

3: Inject AwesomeConfiguration

Done.

 

JPA ‚Äď Associations @OneToOne , @OneToMany, @ManyToOne, @ManyToMany part 3

Previously I wrote about OneToMany and ManyToOne and OneToOne associations, in this post I will show you how to handle ManyToMany associations.

Example that I will be using is classical example of many to many association where we have a teacher that can can teach  many students and a student that can be thought by multiple teachers. To do this I have created two entities Teacher and Student :

 

When many to many association is created we will have three tables STUDENT and TEACHER and TEACHER_STUDENT. Last one binds two tables together with two foreign keys STUDENT_FK_ and TEACHER_FK_ pointing to their primary keys.

Observe how to setup owning side of the association with @JoinTable you can specify table name and with two @JoinColumn one for owning and inverse side. Both JoinColumn specify names for foreign keys.

 

Unit Test

To make sure all works tests should always be created

It is important to note that both sides must be updated in order to make all work properly. Here are those two lines.

This covers all JPA associations types.

 

 

JPA – Associations @OneToOne , @OneToMany, @ManyToOne, @ManyToMany part 2

In previous post I wrote about @OneOnOne association, now I will go trough oneToMany and manyToOne associations with examples.

This associations are used to present that list of entities are part of other “bigger” entity, for example company can have several departments. Department is the part of the company and company is consisted of several departments.

Import is to note that if company is deleted then department is destroyed as well. Why is this important? Because if you setup cascade in the wrong way you might delete important information from your database.

Entities

 

There is detailed explanation in previous post about annotations @Entity, @Table, @Id, @Column, @GeneratedValue so I will focus only on @OneToMany and @ManyToOne.

There are two sides of the coin same as there are two sides of association, there is owning side and inverse side, one side has joinColumn and other has mappedBy property filled. Owning side related table has foreign key to the inverse related table.

FetchType

When ever one has an association there is a question of FetchType value. Two options there are to be picked from EAGER or LAZY. Difference is only that if EAGER option is selected data is loaded right away and if LAZY option is selected data is loaded after the request. This difference can be used into your advantage depending of how you use the data. It is important to note that eager option takes more time to execute, since it is bigger sql query right?

Lets see traverse problem:

If we have LAZY option selected every time getDepartments method is called database will be pinged for new data, this can be very slow in case of many companies.

If we have EAGER option, what if we have company with 10000 departments, do we really need to load all of them every time? Or we can get company first and then filter through the departments …

EAGER vs LAZY depends of the problem that is supposed to be solved, so think first and code after is the mantra here.

 

ForeignKey

@JoingColumn has many properties, few that are important are nullable and foreignKey.

Nullable property set to false tells JPA that Department must have the Company attached. This will translate into notNull column in the related sql table.
ForeignKey property specifies SQL foreign key details in this case its name, if this property is not filled JPA will find suitable name for your foreign key.

 

Spring Repository

There are two entities and two Spring repositories with CRUD methods. Additionally I have added findAll that returns the java.util.List.

Unit Tests

To demonstrate that all works as expected 3 tests are created

  1. Test Create Company with Departments in one save action.
  2. Test create Company and connect it with new Department, here i have two save actions one to create company and other to create department.
  3. Test Cascade deletion of Department, company is deleted and with it departmetns are deleted as well automatically.

Two lines here are most important :

Here both sides of the association are maintained and without it of course is will not work.

 

In above test I have created company with out any departments then new department is created and added to the company. Rest of the code just validates.

 

Cascade delete works as it is expected, when company is deleted all departments go with it.

In the next post I will talk about association ManyToMany using example Teacher Student. Here teacher can tech more then one student and student can be thought by more then one teacher.

 

JPA – Associations @OneToOne , @OneToMany, @ManyToOne, @ManyToMany part 1

JPA entities are usually related to other entities. There are in total 4 types of associations

  • @OneToOne association is used when one entity has only one other entity that it relates to. Example of this association is Employee and EmployeeDetail. Each employee has( or can have) only one detail.
  • @OneToMany, is used when entity is related to many entities. Example is Company that has many Departments.
  • @ManyToOne is opposite from previous association. In this case Department is related to one Company.
  • @ManyToMany, example of this association¬†is a Teacher that can tech many students and Student that can be thought by many teachers.

@OneOnOne

To demonstrate this association I will use example where Employee has EmployeeDetail.

  • @Entity annotates this class as JPA entity
  • @Table specifies table name, in this case EMPLOYEE
  • Primary column as identity is specified using using @Id and @GeneratedValue
  • @Column specifies column name, length and is null among with other properties that can be specified.

In above entities there are two @OneToOne annotated properties to define both sides of the association, owning and inverse side.

Questions that we need to answer are:

  • Foreign key is going to be created in which table?
  • Who is the owner if the association?
  • If one entity is deleted is other entity going to be deleted as well?

Looking to above configuration foreign key is going to be created in table that is related to entity EmplyeeDetail. This is specified using  @JoinColumn(name = EMPLOYEE_ID_) , name also specifies the name of the column in the database table.

Owner of association is EmployeeDetail entity. Not owning( or inverse) side must have mappedBy attribute in its OneToOne annotation.

When Employee is deleted EmployeeDetail should be deleted as well. This is specified by cascade being located in Employee entity.

UnitTests

To make sure this works I have created two JpaRepository interfaces that are used.

CrudRepository interface has CRUD methods that are going to be used in unit test.

What is important to note is when creating Employee and EmployeeDetail both sides of association  must be maintained.

Cascade Delete Test

First I will load both employee and employeeDetail from the database to prove that they both exist. Of course both entities are created in before method that you can see above.

Then I delete the employee and check did this delete employeeDetail as well.

Why was the EmployeeDetail deleted?

It is deleted because of cascade = CascadeType.ALL specified in Employee entity. It is important to thing before so that you do not automatically remove wrong entities.