Cassandra - Lab 4
In this lab, we will learn how to UDT.
1. Define the Director Entity
Steps
- Create a class called
Directorin theexpert.os.labs.persistencepackage -
Define the class with the
@Entityannotation -
Add the fields as specified in the provided code adding the
@Columnannotations for all -
Implement constructors, setter methods,
equals,hashCode, andtoStringmethod.
Expected results
- Entity
Directorcreated
Solution
Click to see...
import jakarta.nosql.Column;
import jakarta.nosql.Entity;
import java.util.Set;
@Entity
public class Director {
@Column
private String name;
@Column
private Set<String> movies;
public Director() {
}
public Director(String name, Set<String> movies) {
this.name = name;
this.movies = movies;
}
public void setName(String name) {
this.name = name;
}
public void setMovies(Set<String> movies) {
this.movies = movies;
}
@Override
public String toString() {
return "Director{" +
"name='" + name + '\'' +
", movies=" + movies +
'}';
}
}
2. Implement the Builder class
Steps
- Create a class called
DirectorBuilderin theexpert.os.labs.persistencepackage -
Add the same fields we had previously added to the
Directorclass, without the annotations- note that we need to initialize the
moviesattribute
- note that we need to initialize the
-
Add the builder methods for each field
- for the
movies field, add a singlemovieto theSet
- for the
- Add the
build()method creating a new instance ofDirectorusing its constructor - In the
Directorclass add the builder method referring to theDirectorBuilder
Expected results
- Builder class
DirectorBuildercreated
Solution
Click to see...
import java.util.Set;
public class DirectorBuilder {
private String name;
private Set<String> movies;
public DirectorBuilder name(String name) {
this.name = name;
return this;
}
public DirectorBuilder addMovie(String movie) {
this.movies.add(movie)
return this;
}
public Director build() {
return new Director(name, movies);
}
}
3. Define the Movie Entity
Steps
- Create a class called
Moviein theexpert.os.labs.persistencepackage - Define the class with the
@Entityannotation -
Define instance variables for
name,age, anddirector, where thenameis the ID and must have the@Idannotation and the other attributes the@Columnannotation -
Annotate the
directorfield with@UDT("director")from the packageorg.eclipse.jnosql.databases.cassandra.mappingto specify that it's a User-Defined Type (UDT) with the name "director" -
Implement the constructor, getter, setters,
equals,hashCode, andtoStringmethods for the class
Expected results
- Entity
Directorcreated
Solution
Click to see...
import jakarta.nosql.Column;
import jakarta.nosql.Entity;
import jakarta.nosql.Id;
import org.eclipse.jnosql.databases.cassandra.mapping.UDT;
@Entity
public class Movie {
@Id("name")
private String name;
@Column
private Integer age;
@Column
@UDT("director")
private Director director;
public Movie(String name, Integer age, Director director) {
this.name = name;
this.age = age;
this.director = director;
}
// getters and setters ignored
@Override
public String toString() {
return "Movie{" +
"name='" + name + '\'' +
", age=" + age +
", director=" + director +
'}';
}
}
4. Define the Movie Repository
Steps
- Create an interface called
MovieRepositoryin theexpert.os.labs.persistencepackage - Annotate the interface with
@Repositoryusing the package fromjakarta.data.repositoryto indicate it's a Jakarta Data repository -
Extend the
CassandraRepositoryinterface from the packageorg.eclipse.jnosql.databases.cassandra.mappingand specify the entity type (Movie) and the ID type (String) as type parameters -
Define the custom query
findByAge() -
Define a custom query
findAllQuery()adding the@CQLannotation from the packageorg.eclipse.jnosql.databases.cassandra.mappingwhere its parameter have the following queryselect * from developers.Movie
Expected results
- Repository
MovieRepositorycontaining two custom queries
Solution
Click to see...
import jakarta.data.repository.Repository;
import org.eclipse.jnosql.databases.cassandra.mapping.CQL;
import org.eclipse.jnosql.databases.cassandra.mapping.CassandraRepository;
import java.util.List;
@Repository
public interface MovieRepository extends CassandraRepository<Movie, String> {
List<Movie> findByAge(Integer age);
@CQL("select * from developers.Movie")
List<Movie> findAllQuery();
}
5. Create the execution class for Cassandra UDT
Steps
- Create a class called
AppCassandraUDTin theexpert.os.labs.persistencepackage -
Add a main method
-
Set up a try-with-resources block, inside the
mainmethod, to manage the Jakarta EESeContainerthat is responsible for dependency injection and managing resources -
Obtain an instance of the
MovieRepositoryinterface using Jakarta EE'sSeContainer. It is done by selecting and getting an instance of the repository -
Add the following
Movieinstances with its dataMovie matrix = new Movie(); matrix.setName("The Matrix"); matrix.setAge(1999); matrix.setDirector(Director.builder().name("Lana Wachowski") .add("The Matrix").add("The Matrix Reloaded").add("Assassins").build()); Movie fightClub = new Movie(); fightClub.setName("Fight Club"); fightClub.setAge(1999); fightClub.setDirector(Director.builder().name("David Fincher") .add("Fight Club").add("Seven").add("The Social Network").build()); Movie americanBeauty = new Movie(); americanBeauty.setName("American Beauty"); americanBeauty.setAge(1999); americanBeauty.setDirector(Director.builder().name("Sam Mendes") .add("Spectre").add("SkyFall").add("American Beauty").build()); -
Use the repository to save all the created
Movie, as aListof entities to Cassandra usingrepository.saveAll() -
Retrieve and print all movies using
repository.findAllQuery() -
Retrieve and print movies from the year 1999 using
repository.findByAge(1999) -
Define a private constructor for the
AppCassandraUDTclass to prevent instantiation since it contains only static methods: -
Run the
main()method
Expected results
-
The following output
All movies = [Movie{name='Fight Club', age=1999, director=Director{name='David Fincher', movies=[Fight Club, Seven, The Social Network]}}, Movie{name='American Beauty', age=1999, director=Director{name='Sam Mendes', movies=[American Beauty, SkyFall, Spectre]}}, Movie{name='The Matrix', age=1999, director=Director{name='Lana Wachowski', movies=[The Matrix, Assassins, The Matrix Reloaded]}}] Movies from 1999 = [Movie{name='Fight Club', age=1999, director=Director{name='David Fincher', movies=[Fight Club, Seven, The Social Network]}}, Movie{name='American Beauty', age=1999, director=Director{name='Sam Mendes', movies=[American Beauty, SkyFall, Spectre]}}, Movie{name='The Matrix', age=1999, director=Director{name='Lana Wachowski', movies=[The Matrix, Assassins, The Matrix Reloaded]}}]
Solution
Click to see...
import jakarta.enterprise.inject.se.SeContainer;
import jakarta.enterprise.inject.se.SeContainerInitializer;
import java.util.List;
public class AppCassandraUDT {
public static void main(String[] args) {
try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
MovieRepository repository = container.select(MovieRepository.class).get();
Movie matrix = new Movie();
matrix.setName("The Matrix");
matrix.setAge(1999);
matrix.setDirector(Director.builder().name("Lana Wachowski")
.addMovie("The Matrix").addMovie("The Matrix Reloaded").addMovie("Assassins").build());
Movie fightClub = new Movie();
fightClub.setName("Fight Club");
fightClub.setAge(1999);
fightClub.setDirector(Director.builder().name("David Fincher")
.addMovie("Fight Club").add("Seven").addMovie("The Social Network").build());
Movie americanBeauty = new Movie();
americanBeauty.setName("American Beauty");
americanBeauty.setAge(1999);
americanBeauty.setDirector(Director.builder().name("Sam Mendes")
.addMovie("Spectre").addMovie("SkyFall").addMovie("American Beauty").build());
repository.saveAll(List.of(matrix, fightClub, americanBeauty));
List<Movie> allMovies = repository.findAllQuery();
System.out.println("All movies = " + allMovies);
List<Movie> movieByAge = repository.findByAge(1999);
System.out.println("Movies from 1999 = " + movieByAge);
}
}
public AppCassandraUDT() {
}
}