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
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

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
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

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • A Practical Guide to Creating a Spring Modulith Project
  • Providing Enum Consistency Between Application and Data
  • Distributed Tracing System (Spring Cloud Sleuth + OpenZipkin)
  • Java, Spring Boot, and MongoDB: Performance Analysis and Improvements

Trending

  • Cookies Revisited: A Networking Solution for Third-Party Cookies
  • Concourse CI/CD Pipeline: Webhook Triggers
  • Artificial Intelligence, Real Consequences: Balancing Good vs Evil AI [Infographic]
  • Immutable Secrets Management: A Zero-Trust Approach to Sensitive Data in Containers
  1. DZone
  2. Coding
  3. Frameworks
  4. Working With Spring Boot and Hazelcast (Distributed Cache)

Working With Spring Boot and Hazelcast (Distributed Cache)

How to create a simple Spring Boot application, using Hazelcast as a Distributed Cache. This can help improve database performance.

By 
Diraj Pandey user avatar
Diraj Pandey
·
Feb. 25, 21 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
22.9K Views

Join the DZone community and get the full member experience.

Join For Free

Hazelcast provides central and predictable scaling of applications via in-memory access to frequently used data and across an elastically scalable data grid. These techniques both reduce the query load on databases and help improve application speed.

Spring Boot is often used to create stand-alone, production-grade Spring-based Applications that you can 'just run.'

Let us create a simple Spring Boot application with Hazelcast as a Distributed Cache.

Below is an implementation of a local cache for better performance.

Implementation of a local cache

Here, when a request is made from an application, if that data is available in the cache, then we don’t have to make a call to the database, or if data is not available in the cache, then a request is made to the database.

We deploy the application as a distributed system, as below, for better load balancing.

Deployment as a distributed system

Implementation

Here is the implementation of a simple spring boot application. 

First, we make changes in the pom file by adding a Hazelcast dependency, as below:

XML
 




x


 
1
<dependency>
2
    <groupId>com.hazelcast</groupId>
3
    <artifactId>hazelcast</artifactId>
4
</dependency>



We also add a plugin where the entry point to the application is provided in the distributed system. Since DoctorApplication is the main class it is added in the plugin as below:

XML
 




xxxxxxxxxx
1


 
1
<plugin>
2
    <groupId>org.springframework.boot</groupId>
3
    <artifactId>spring-boot-maven-plugin</artifactId>
4
    <configuration>
5
        <mainClass>com.rbitcs.DoctorApplication</mainClass>
6
    </configuration>
7
</plugin>



POM file should look like below:

pom.xml

XML
 




xxxxxxxxxx
1
55


 
1
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
    <modelVersion>4.0.0</modelVersion>
4
    <groupId>com.rbitcs</groupId>
5
    <artifactId>hazelcast-springboot</artifactId>
6
    <version>0.0.1-SNAPSHOT</version>
7
8
    <parent>
9
        <groupId>org.springframework.boot</groupId>
10
        <artifactId>spring-boot-starter-parent</artifactId>
11
        <version>2.2.5.RELEASE</version>
12
        <relativePath /> <!-- lookup parent from repository -->
13
    </parent>
14
15
    <properties>
16
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
18
        <java.version>1.8</java.version>
19
    </properties>
20
    
21
    <dependencies>
22
        <dependency>
23
            <groupId>org.springframework.boot</groupId>
24
            <artifactId>spring-boot-starter-web</artifactId>
25
        </dependency>
26
        
27
        <dependency>
28
            <groupId>org.springframework.boot</groupId>
29
            <artifactId>spring-boot-starter-data-jpa</artifactId>
30
        </dependency>
31
        
32
        <dependency>
33
            <groupId>mysql</groupId>
34
            <artifactId>mysql-connector-java</artifactId>
35
            <scope>runtime</scope>
36
        </dependency>
37
        
38
        <dependency>
39
            <groupId>com.hazelcast</groupId>
40
            <artifactId>hazelcast</artifactId>
41
        </dependency>
42
    </dependencies>
43
44
    <build>
45
        <plugins>
46
            <plugin>
47
                <groupId>org.springframework.boot</groupId>
48
                <artifactId>spring-boot-maven-plugin</artifactId>
49
                <configuration>
50
                    <mainClass>com.RBITCS.DoctorApplication</mainClass>
51
                </configuration>
52
            </plugin>
53
        </plugins>
54
    </build>
55
</project>



We will be using IMAP provided by hazelmap as the cache. IMAP implements a map interface. Below is the Spring Boot application where beans use IMAP for caching in configuring the Hazelcast instance.

Java
 




xxxxxxxxxx
1
43


 
1
package com.rbitcs;
2

          
3
import java.util.HashMap;
4
import java.util.Map;
5

          
6
import org.springframework.boot.SpringApplication;
7
import org.springframework.boot.autoconfigure.SpringBootApplication;
8
import org.springframework.context.annotation.Bean;
9
import org.springframework.context.annotation.Configuration;
10
import com.hazelcast.config.Config;
11
import com.hazelcast.config.ManagementCenterConfig;
12
import com.hazelcast.core.Hazelcast;
13
import com.hazelcast.core.HazelcastInstance;
14
import com.hazelcast.core.IMap;
15
import com.codeusingjava.model.UserAccount;
16

          
17
import com.rbitcs.model.Doctors;
18

          
19
@SpringBootApplication
20
public class HospitalApplication {
21

          
22
    public static void main(String[] args) {
23
        SpringApplication.run(HospitalApplication.class, args);
24
    }
25

          
26
    @Bean
27
    public Config hazelCastConfig() {
28
        return new Config().setManagementCenterConfig(
29
                new ManagementCenterConfig().setEnabled(true).setUrl("http://localhost:8080/hazelcast-mancenter"));
30

          
31
    }
32

          
33
    @Bean
34
    public HazelcastInstance hazelcastInstance(Config hazelCastConfig) {
35
        return Hazelcast.newHazelcastInstance(hazelCastConfig);
36
    }
37

          
38
    @Bean
39
    public Map<String, Doctor> doctorMap(HazelcastInstance hazelcastInstance) {
40
        return hazelcastInstance.getMap("doctorMap");
41
    }
42
}



Since we are making use of IMAP we need to serialize the object. Here, Doctor object should be serializable.

Java
 




xxxxxxxxxx
1
65


 
1
package com.rbitcs.model;
2

          
3
import java.io.Serializable;
4

          
5
import javax.persistence.Column;
6
import javax.persistence.Entity;
7
import javax.persistence.GeneratedValue;
8
import javax.persistence.GenerationType;
9
import javax.persistence.Id;
10
import javax.persistence.Table;
11

          
12
@Entity
13
@Table(name = "doctor")
14
public class Doctor implements Serializable {
15

          
16
    private static final long serialVersionUID = 1L;
17

          
18
    @Id
19
    @Column(name = "id")
20
    @GeneratedValue(strategy = GenerationType.IDENTITY)
21
    private Long id;
22

          
23
    @Column(name = "doctorNumber")
24
    private String doctorNumber;
25

          
26
    @Column(name = "name")
27
    private String name;
28

          
29
    @Column(name = "address")
30
    private String address;
31

          
32
    public String getName() {
33
        return name;
34
    }
35

          
36
    public void setName(String name) {
37
        this.name = name;
38
    }
39

          
40
    public String getAddress() {
41
        return address;
42
    }
43

          
44
    public void setAddress(String address) {
45
        this.address = address;
46
    }
47

          
48
    public long getBalance() {
49
        return balance;
50
    }
51

          
52
    public void setBalance(long balance) {
53
        this.balance = balance;
54
    }
55

          
56
    public String getDoctorNumber() {
57
        return doctorNumber;
58
    }
59

          
60
    public void setDoctorNumber(String doctorNumber) {
61
        this.doctorNumber = doctorNumber;
62
    }
63
}
64

          


Let us create a controller and auto-wire doctorMap:

Java
 




xxxxxxxxxx
1
52


 
1
package com.rbitcs.controller;
2

          
3
import java.util.List;
4
import java.util.Map;
5
import java.util.Optional;
6

          
7
import org.springframework.beans.factory.annotation.Autowired;
8
import org.springframework.web.bind.annotation.DeleteMapping;
9
import org.springframework.web.bind.annotation.GetMapping;
10
import org.springframework.web.bind.annotation.PathVariable;
11
import org.springframework.web.bind.annotation.PostMapping;
12
import org.springframework.web.bind.annotation.RequestBody;
13
import org.springframework.web.bind.annotation.RequestMapping;
14
import org.springframework.web.bind.annotation.RestController;
15

          
16
import com.rbitcs.db.DoctorRepository;
17
import com.rbitcs.model.Doctor;
18

          
19
@RestController
20
@RequestMapping(path = "doctors")
21
public class DoctorController {
22

          
23
    @Autowired
24
    private DoctorRepository doctorRepository;
25

          
26
    @Autowired
27
    private Map<String, Doctor> doctorMap;
28

          
29
    @GetMapping(path = { "/get/{doctorNumber}" })
30
    public Doctor getDoctor(@PathVariable("doctorNumber") String doctorNumber) {
31
        /First call is to check if doctormap has doctor details if yes, return the value otherwise call database.
32
        Doctor doctor = (doctortMap.get(doctorNumber) != null) ? doctorMap.get(doctorNumber)
33
                : DoctorRepository.findByDoctorNumber(doctorNumber);
34
        return doctor;
35
    }
36

          
37
    @PostMapping("/add")
38
    public void createDoctor(@RequestBody Doctor doctor) {
39
        //save doctor details in cache
40
        doctorMap.put(doctor.getDoctorNumber(), doctor);
41
        doctorRepository.save(doctor);
42
    }
43

          
44
    @DeleteMapping(path = { "/delete/{doctorNumber}" })
45
    public Doctor deleteDoctor(@PathVariable("doctorNumber") String doctorNumber) {
46
        //remove doctor details from both cache and database
47
        doctorMap.remove(doctorNumber);
48
        return doctorRepository.deleteByDoctorNumber(doctorNumber);
49
    }
50
}
51

          



Start Application

Nice! We have made all the necessary changes.

Let us start the application with the below commands:

java -Dserver.port='8081' -jar boot-hazel-0.0.1-SNAPSHOT.jar
java -Dserver.port='8082' -jar boot-hazel-0.0.1-SNAPSHOT.jar
java -Dserver.port='8083' -jar boot-hazel-0.0.1-SNAPSHOT.jar


Let's say we have started 3 instances at 3 different ports (8081, 8082, 8083).

When a doctor's details are stored via the 8081 port application, then the same object can be retrieved from the 8083 port or 8082 port application from the cache and it does not need to make a call to the database.

After the above implementation, the architecture looks like below:

Post-implementation architecture

Here all the nodes are synchronized and the same date will be retrieved when requested from any of the JVM with better performance and better load balance.

Spring Framework Spring Boot Cache (computing) Hazelcast application

Opinions expressed by DZone contributors are their own.

Related

  • A Practical Guide to Creating a Spring Modulith Project
  • Providing Enum Consistency Between Application and Data
  • Distributed Tracing System (Spring Cloud Sleuth + OpenZipkin)
  • Java, Spring Boot, and MongoDB: Performance Analysis and Improvements

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!