diff --git a/persistence-modules/spring-data-cassandra-2/pom.xml b/persistence-modules/spring-data-cassandra-2/pom.xml
index 740c04d2a0..01b5ce5ed6 100644
--- a/persistence-modules/spring-data-cassandra-2/pom.xml
+++ b/persistence-modules/spring-data-cassandra-2/pom.xml
@@ -65,6 +65,18 @@
java-driver-mapper-runtime
4.15.0
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.jupiter.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.jupiter.version}
+ test
+
@@ -88,10 +100,10 @@
11
- 3.1.11
- 1.15.3
+ 3.4.15
+ 1.19.0
1.1.0
- 5.6.2
+ 5.9.3
\ No newline at end of file
diff --git a/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/CassandraApplication.java b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/CassandraApplication.java
new file mode 100644
index 0000000000..ecc50cbf40
--- /dev/null
+++ b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/CassandraApplication.java
@@ -0,0 +1,12 @@
+package org.baeldung.cassandra.inquery;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class CassandraApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(CassandraApplication.class, args);
+ }
+}
diff --git a/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/model/Product.java b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/model/Product.java
new file mode 100644
index 0000000000..c9007e8405
--- /dev/null
+++ b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/model/Product.java
@@ -0,0 +1,49 @@
+package org.baeldung.cassandra.inquery.model;
+
+import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
+import org.springframework.data.cassandra.core.mapping.Column;
+import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn;
+import org.springframework.data.cassandra.core.mapping.Table;
+
+import java.util.Objects;
+import java.util.UUID;
+
+@Table
+public class Product {
+
+ @PrimaryKeyColumn(name = "product_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
+ private UUID productId;
+
+ @PrimaryKeyColumn(name = "product_name", ordinal = 1, type = PrimaryKeyType.CLUSTERED)
+ private String productName;
+
+ @Column("description")
+ private String description;
+
+ @Column("price")
+ private double price;
+
+ public Product(UUID productId, String productName, String description, double price) {
+ this.productId = productId;
+ this.productName = productName;
+ this.description = description;
+ this.price = price;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Product product = (Product) o;
+ return productId.equals(product.productId) && productName.equals(product.productName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(productId, productName);
+ }
+}
diff --git a/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/repository/ProductRepository.java b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/repository/ProductRepository.java
new file mode 100644
index 0000000000..176ca4d786
--- /dev/null
+++ b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/repository/ProductRepository.java
@@ -0,0 +1,20 @@
+package org.baeldung.cassandra.inquery.repository;
+
+import org.baeldung.cassandra.inquery.model.Product;
+import org.springframework.data.cassandra.repository.CassandraRepository;
+import org.springframework.data.cassandra.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.UUID;
+
+@Repository
+public interface ProductRepository extends CassandraRepository {
+
+ @Query("select * from product where product_id in :productIds")
+ List findByProductIds(@Param("productIds") List productIds);
+
+ @Query("select * from product where product_id = :productId and product_name in :productNames")
+ List findByProductIdAndNames(@Param("productId") UUID productId, @Param("productNames") List productNames);
+}
diff --git a/persistence-modules/spring-data-cassandra-2/src/test/java/org/baeldung/cassandra/inquery/ProductRepositoryNestedLiveTest.java b/persistence-modules/spring-data-cassandra-2/src/test/java/org/baeldung/cassandra/inquery/ProductRepositoryNestedLiveTest.java
new file mode 100644
index 0000000000..3d2433814e
--- /dev/null
+++ b/persistence-modules/spring-data-cassandra-2/src/test/java/org/baeldung/cassandra/inquery/ProductRepositoryNestedLiveTest.java
@@ -0,0 +1,115 @@
+package org.baeldung.cassandra.inquery;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.utils.UUIDs;
+import org.baeldung.cassandra.inquery.model.Product;
+import org.baeldung.cassandra.inquery.repository.ProductRepository;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.testcontainers.containers.CassandraContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+import java.util.List;
+import java.util.UUID;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+
+@Testcontainers
+@SpringBootTest
+class ProductRepositoryIntegrationTest {
+
+ private static final String KEYSPACE_NAME = "mynamespace";
+
+ @Container
+ private static final CassandraContainer cassandra = (CassandraContainer) new CassandraContainer("cassandra:3.11.2")
+ .withExposedPorts(9042);
+
+ @BeforeAll
+ static void setupCassandraConnectionProperties() {
+ System.setProperty("spring.data.cassandra.keyspace-name", KEYSPACE_NAME);
+ System.setProperty("spring.data.cassandra.contact-points", cassandra.getHost());
+ System.setProperty("spring.data.cassandra.port", String.valueOf(cassandra.getMappedPort(9042)));
+ createKeyspace(cassandra.getCluster());
+ }
+
+ static void createKeyspace(Cluster cluster) {
+ try (Session session = cluster.connect()) {
+ session.execute("CREATE KEYSPACE IF NOT EXISTS " + KEYSPACE_NAME + " WITH replication = \n" +
+ "{'class':'SimpleStrategy','replication_factor':'1'};");
+ }
+ }
+
+ @Nested
+ class ApplicationContextLiveTest {
+ @Test
+ void givenCassandraContainer_whenSpringContextIsBootstrapped_thenContainerIsRunningWithNoExceptions() {
+ assertThat(cassandra.isRunning()).isTrue();
+ }
+ }
+
+ @Nested
+ class ProductRepositoryLiveTest {
+
+ @Autowired
+ private ProductRepository productRepository;
+
+ @Test
+ void givenValidProductsIsFetched_whenFindByProductIdsIsCalled_thenProductIsReturned() {
+ UUID productId1 = UUIDs.timeBased();
+ UUID productId2 = UUIDs.timeBased();
+ UUID productId3 = UUIDs.timeBased();
+ Product product1 = new Product(productId1, "Apple", "Apple v1", 12.5);
+ Product product2 = new Product(productId2, "Apple v2", "Apple v2", 15.5);
+ Product product3 = new Product(productId3, "Banana", "Banana v1", 5.5);
+ Product product4 = new Product(productId3, "Banana v2", "Banana v2", 15.5);
+
+ productRepository.saveAll(List.of(product1, product2, product3, product4));
+
+ List existingProducts = productRepository.findByProductIds(List.of(productId1, productId2));
+ assertEquals(2, existingProducts.size());
+ assertTrue(existingProducts.contains(product1));
+ assertTrue(existingProducts.contains(product2));
+ }
+
+ @Test
+ void givenExistingProducts_whenFindByIdAndNamesIsCalled_thenProductIsReturned() {
+ UUID productId1 = UUIDs.timeBased();
+ UUID productId2 = UUIDs.timeBased();
+ Product product1 = new Product(productId1, "Apple", "Apple v1", 12.5);
+ Product product2 = new Product(productId1, "Apple v2", "Apple v2", 15.5);
+ Product product3 = new Product(productId2, "Banana", "Banana v1", 5.5);
+ Product product4 = new Product(productId2, "Banana v2", "Banana v2", 15.5);
+
+ productRepository.saveAll(List.of(product1, product2, product3, product4));
+
+ List existingProducts = productRepository.findByProductIdAndNames(productId1,
+ List.of(product1.getProductName(), product2.getProductName()));
+ assertEquals(2, existingProducts.size());
+ assertTrue(existingProducts.contains(product1));
+ assertTrue(existingProducts.contains(product2));
+ }
+
+ @Test
+ void givenNonExistingProductName_whenFindByIdAndNamesIsCalled_thenProductIsReturned() {
+ UUID productId1 = UUIDs.timeBased();
+ UUID productId2 = UUIDs.timeBased();
+ Product product1 = new Product(productId1, "Apple", "Apple v1", 12.5);
+ Product product2 = new Product(productId1, "Apple v2", "Apple v2", 15.5);
+ Product product3 = new Product(productId2, "Banana", "Banana v1", 5.5);
+ Product product4 = new Product(productId2, "Banana v2", "Banana v2", 15.5);
+
+ productRepository.saveAll(List.of(product1, product2, product4));
+
+ List existingProducts = productRepository.findByProductIdAndNames(productId1,
+ List.of(product3.getProductName()));
+ assertEquals(0, existingProducts.size());
+ }
+ }
+}