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
- Creating spring boot Cassandra CRUD app
- Testing the CRUD APIs
- Conclusion
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.

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.

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.

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.

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

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.

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

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.