Spring Boot Cassandra CRUD Example

Cassandra is an open-source No-SQL data store that supports wide-column data storage. Spring boot provides the required dependency libraries to connect to the Cassandra data store. We can leverage the spring data Cassandra library to perform the CRUD operation with minimal code.

In this article, we will learn how to perform CRUD operations using Spring boot and Cassandra data store.

Version details:

  • Cassandra docker image version: 4.0.6
  • Spring boot version: 2.7.1

Table of Contents

Set up the Cassandra data store

We will use Cassandra’s latest docker image and run the container locally. The latest docker image version at the time of writing this article is 4.0.6

Run the below command from the terminal to download and start the Cassandra docker container.

docker run --name my-cassandra -p 9042:9042 -d cassandra:latest

In a Cassandra cluster, the keyspace is an outermost object that determines how data gets replicated on nodes.

Once the Cassandra container is up, we can set up the Cassandra keyspace by entering into the Cassandra shell.

docker exec -it my-cassandra bash

Once we open the Cassandra bash terminal, we can enter the CQL shell by running the below command.

cqlsh

The below images show the CQL shell opened from running the above command.

cassandra cql shell

Now, enter the below script to create a Cassandra key-space with the name student_keyspace.

create keyspace student_keyspace with replication={'class':'SimpleStrategy', 'replication_factor':1} and durable_writes=true;

To verify the created key space, we can use the below command.

desc keyspaces;

We should get our newly created Cassandra key space as shown below.

cassandra create keyspace.

Creating spring boot Cassandra CRUD app

Create a spring boot application with spring-boot-starter-web, lombok dependencies.

Spring boot provides spring-boot-starter-data-cassandra dependency, which allows us to perform CRUD operations from our application with the Cassandra database.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>

Next, we will add the Cassandra connection details to our application’s configuration file.

spring:
  data:
    cassandra:
      keyspace-name: student_keyspace
      schema-action: recreate
      local-datacenter: datacenter1
      contact-points: localhost
      port: 9042

Creating the cassandra entities

Now, let’s create a Student Cassandra entity class that holds the student details like name, grade, address, subjects, etc.

We are generating time based UUID as the primary key of the student entity.

Also, we also have to annotate the primary key column with the @PrimaryKey annotation.

We can explicitly specify the column name with the help of @Column annotation.

For the address field, let’s create a custom Cassandra User Defined Type(UDT) called AddressUDT.

Also, add a collection of SubjectUDT Cassandra User Defined Type that specifies the student’s subject details.

package com.asbnotebook.domain;

import com.datastax.oss.driver.api.core.uuid.Uuids;
import lombok.Data;
import org.springframework.data.cassandra.core.mapping.Column;
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
import org.springframework.data.cassandra.core.mapping.Table;

import java.util.List;
import java.util.UUID;

@Data
@Table("students")
public class Student {

    @PrimaryKey
    private UUID id = Uuids.timeBased();

    @Column("student_name")
    private String name;

    private Integer grade;

    @Column("address")
    private AddressUDT address;

    @Column("subjects")
    private List<SubjectUDT> subjects;
}

Let’s create the AddreddUDT Cassandra User Defined Type(UDT) class and add the student’s address details.

package com.asbnotebook.domain;

import lombok.Data;
import org.springframework.data.cassandra.core.mapping.Column;
import org.springframework.data.cassandra.core.mapping.UserDefinedType;

@Data
@UserDefinedType("address")
public class AddressUDT {

    private String street;
    @Column("door_number")
    private Integer doorNo;
    @Column("pin_code")
    private Integer pinCode;
}

Finally, create a SubjectUDT Cassandra User Defined Type(UDT) class, as shown below.

package com.asbnotebook.domain;

import lombok.Data;
import org.springframework.data.cassandra.core.mapping.UserDefinedType;

@Data
@UserDefinedType("subject")
public class SubjectUDT {

    private String name;
}

Creating the repository

We can leverage the Spring Data Cassandra library’s support for a built-in repository that helps to perform basic CRUD operations with the Cassandra database.

Create an interface called StudentRepository that extends the CassandraRepository interface, as shown below.

package com.asbnotebook.repository;

import com.asbnotebook.domain.Student;
import org.springframework.data.cassandra.repository.CassandraRepository;

import java.util.UUID;

public interface StudentRepository extends CassandraRepository<Student, UUID> {
}

The service layer

Let’s create the service layer and add the required CRUD methods.

Create a StudentService class as shown below. The service layer invokes the Cassandra repository that we created earlier.

package com.asbnotebook.service;

import com.asbnotebook.domain.Student;
import com.asbnotebook.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;

@Service
public class StudentService {

    @Autowired
    private StudentRepository studentRepository;

    public Student saveStudent(Student student){
        return studentRepository.save(student);
    }

    public List<Student> getStudents(){
        return studentRepository.findAll();
    }

    public Student updateStudent(Student student, String id){
        var existingStudent = studentRepository.findById(UUID.fromString(id));
        if(!existingStudent.isPresent())
            throw new RuntimeException("Student not found!!");
        student.setId(UUID.fromString(id));
        return studentRepository.save(student);
    }

    public String deleteStudent(String id){
        studentRepository.deleteById(UUID.fromString(id));
        return "Student deleted successfully";
    }
}

Creating the APIs

Finally, add the REST APIs that support the CRUD operation.

package com.asbnotebook.controller;

import com.asbnotebook.domain.Student;
import com.asbnotebook.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class StudentController {

    @Autowired
    private StudentService studentService;

    @GetMapping("/students")
    public List<Student> getStudents(){
        return studentService.getStudents();
    }

    @PostMapping("/students")
    public Student saveStudent(@RequestBody Student student){
        return studentService.saveStudent(student);
    }

    @PutMapping("/students/{id}")
    public Student updateStudent(@RequestBody Student student, @PathVariable("id") String id) {
        return studentService.updateStudent(student, id);
    }

    @DeleteMapping("/students/{id}")
    public String deleteStudent(@PathVariable("id") String id) {
        return studentService.deleteStudent(id);
    }
}

Testing the CRUD APIs

Run the Spring boot application. Let’s test the Cassandra CRUD operations by invoking the REST APIs.

Invoke the POST API to create a Student with the Address and subject details, as shown below.

Spring boot cassandra crud example

Once the Student object is stored in Cassandra DB, we receive the unique UUID as id field, as shown below.

We can also invoke the GET API and confirm that the newly created Student object is available on the Casandra DB.

spring boot cassandra crud example

To update the Student record, use the PUT API as shown below.

spring boot cassandra crud example

We can also verify the Cassandra DB using the CQL shell, as shown below.

Notice that the User Defined Data Types(UDTs) stored a single column which is the main characteristic of Cassandra DB, where it supports wide column storage.

cassandra cqlshel

Finally, to delete the data from Cassandra DB, use the DELETE API by passing the student id, as shown below.

spring boot cassandra crud example

Conclusion

In this article, we saw how to perform CRUD operations with Cassandra DB using the Spring data cassandra library.

We also created CRUD REST APIs and tested the CRUD operation.

Example code is available on Github.

Spring Boot Cassandra CRUD Example
Scroll to top

Discover more from ASB Notebook

Subscribe now to keep reading and get access to the full archive.

Continue reading