diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index acfd171f3b..4637ab7ecc 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -87,6 +87,7 @@ spring-data-jdbc spring-data-keyvalue spring-data-mongodb + spring-data-mongodb-2 spring-data-mongodb-reactive spring-data-neo4j spring-data-redis diff --git a/persistence-modules/spring-data-mongodb-2/README.md b/persistence-modules/spring-data-mongodb-2/README.md new file mode 100644 index 0000000000..817da8d3cf --- /dev/null +++ b/persistence-modules/spring-data-mongodb-2/README.md @@ -0,0 +1,7 @@ +========= + +## Spring Data MongoDB 2 + +### Relevant Articles: +- [Return Only Specific Fields for a Query in Spring Data MongoDB](https://www.baeldung.com/mongodb-return-specific-fields) + diff --git a/persistence-modules/spring-data-mongodb-2/pom.xml b/persistence-modules/spring-data-mongodb-2/pom.xml new file mode 100644 index 0000000000..35353edfe3 --- /dev/null +++ b/persistence-modules/spring-data-mongodb-2/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + spring-data-mongodb-2 + spring-data-mongodb-2 + + + com.baeldung + parent-spring-5 + 0.0.1-SNAPSHOT + ../../parent-spring-5 + + + + + org.springframework.data + spring-data-mongodb + ${org.springframework.data.version} + + + org.mongodb + mongodb-driver-sync + ${mongodb-driver.version} + + + org.springframework + spring-core + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-test + ${spring.version} + test + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + ${embed.mongo.version} + test + + + + + 3.0.3.RELEASE + 4.0.5 + 3.2.6 + + + \ No newline at end of file diff --git a/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/model/InStock.java b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/model/InStock.java new file mode 100644 index 0000000000..6f57808ab0 --- /dev/null +++ b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/model/InStock.java @@ -0,0 +1,46 @@ +package com.baeldung.projection.model; + +import java.util.Objects; + +public class InStock { + + private String wareHouse; + private Integer quantity; + + public InStock(String wareHouse, int quantity) { + this.wareHouse = wareHouse; + this.quantity = quantity; + } + + public String getWareHouse() { + return wareHouse; + } + + public void setWareHouse(String wareHouse) { + this.wareHouse = wareHouse; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + InStock inStock = (InStock) o; + return Objects.equals(wareHouse, inStock.wareHouse) && Objects.equals(quantity, inStock.quantity); + } + + @Override + public int hashCode() { + return Objects.hash(wareHouse, quantity); + } + +} diff --git a/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/model/Inventory.java b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/model/Inventory.java new file mode 100644 index 0000000000..0f4cf6b814 --- /dev/null +++ b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/model/Inventory.java @@ -0,0 +1,71 @@ +package com.baeldung.projection.model; + +import java.util.List; +import java.util.Objects; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.MongoId; + +@Document(collection = "inventory") +public class Inventory { + + @Id + private String id; + private String item; + private String status; + private Size size; + private List inStock; + + public String getId() { + return id; + } + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Size getSize() { + return size; + } + + public void setSize(Size size) { + this.size = size; + } + + public List getInStock() { + return inStock; + } + + public void setInStock(List inStock) { + this.inStock = inStock; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Inventory inventory = (Inventory) o; + return Objects.equals(id, inventory.id) && Objects.equals(item, inventory.item) && Objects.equals(status, inventory.status); + } + + @Override + public int hashCode() { + return Objects.hash(id, item, status); + } + +} diff --git a/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/model/Size.java b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/model/Size.java new file mode 100644 index 0000000000..54af8f09f7 --- /dev/null +++ b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/model/Size.java @@ -0,0 +1,56 @@ +package com.baeldung.projection.model; + +import java.util.Objects; + +public class Size { + + private Double height; + private Double width; + private String uom; + + public Size(Double height, Double width, String uom) { + this.height = height; + this.width = width; + this.uom = uom; + } + + public Double getHeight() { + return height; + } + + public void setHeight(Double height) { + this.height = height; + } + + public Double getWidth() { + return width; + } + + public void setWidth(Double width) { + this.width = width; + } + + public String getUom() { + return uom; + } + + public void setUom(String uom) { + this.uom = uom; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Size size = (Size) o; + return Objects.equals(height, size.height) && Objects.equals(width, size.width) && Objects.equals(uom, size.uom); + } + + @Override + public int hashCode() { + return Objects.hash(height, width, uom); + } + +} diff --git a/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/repository/InventoryRepository.java b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/repository/InventoryRepository.java new file mode 100644 index 0000000000..66b4ef02d5 --- /dev/null +++ b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/projection/repository/InventoryRepository.java @@ -0,0 +1,33 @@ +package com.baeldung.projection.repository; + +import java.util.List; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; + +import com.baeldung.projection.model.Inventory; + +public interface InventoryRepository extends MongoRepository { + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1 }") + List findByStatusIncludeItemAndStatusFields(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, '_id' : 0 }") + List findByStatusIncludeItemAndStatusExcludeIdFields(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'status' : 0, 'inStock' : 0 }") + List findByStatusIncludeAllButStatusAndStockFields(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, 'size.uom': 1 }") + List findByStatusIncludeEmbeddedFields(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'size.uom': 0 }") + List findByStatusExcludeEmbeddedFields(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, 'inStock.quantity': 1 }") + List findByStatusIncludeEmbeddedFieldsInArray(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, 'inStock': { $slice: -1 } }") + List findByStatusIncludeEmbeddedFieldsLastElementInArray(String status); + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/AbstractTestProjection.java b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/AbstractTestProjection.java new file mode 100644 index 0000000000..b197ada7aa --- /dev/null +++ b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/AbstractTestProjection.java @@ -0,0 +1,49 @@ +package com.baeldung.projection; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import com.baeldung.projection.model.InStock; +import com.baeldung.projection.model.Inventory; +import com.baeldung.projection.model.Size; + +abstract class AbstractTestProjection { + + public List getInventories() { + Inventory journal = new Inventory(); + journal.setItem("journal"); + journal.setStatus("A"); + journal.setSize(new Size(14.0, 21.0, "cm")); + journal.setInStock(Collections.singletonList(new InStock("A", 5))); + + Inventory notebook = new Inventory(); + notebook.setItem("notebook"); + notebook.setStatus("A"); + notebook.setSize(new Size(8.5, 11.0, "in")); + notebook.setInStock(Collections.singletonList(new InStock("C", 5))); + + Inventory paper = new Inventory(); + paper.setItem("paper"); + paper.setStatus("D"); + paper.setSize(new Size(8.5, 11.0, "in")); + paper.setInStock(Collections.singletonList(new InStock("A", 60))); + + return Arrays.asList(journal, notebook, paper); + } + + abstract void whenIncludeFields_thenOnlyIncludedFieldsAreNotNull(); + + abstract void whenIncludeFieldsAndExcludeOtherFields_thenOnlyExcludedFieldsAreNull(); + + abstract void whenIncludeAllButExcludeSomeFields_thenOnlyExcludedFieldsAreNull(); + + abstract void whenIncludeEmbeddedFields_thenEmbeddedFieldsAreNotNull(); + + abstract void whenExcludeEmbeddedFields_thenEmbeddedFieldsAreNull(); + + abstract void whenIncludeEmbeddedFieldsInArray_thenEmbeddedFieldsInArrayAreNotNull(); + + abstract void whenIncludeEmbeddedFieldsSliceInArray_thenArrayLengthEqualToSlice(); + +} diff --git a/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/MongoTemplateProjectionUnitTest.java b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/MongoTemplateProjectionUnitTest.java new file mode 100644 index 0000000000..1cd6415a1b --- /dev/null +++ b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/MongoTemplateProjectionUnitTest.java @@ -0,0 +1,223 @@ +package com.baeldung.projection; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.projection.config.ProjectionConfig; +import com.baeldung.projection.model.InStock; +import com.baeldung.projection.model.Inventory; +import com.baeldung.projection.model.Size; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = ProjectionConfig.class) +public class MongoTemplateProjectionUnitTest extends AbstractTestProjection { + + @Autowired + private MongoTemplate mongoTemplate; + + @BeforeEach + void setup() { + List inventoryList = getInventories(); + + mongoTemplate.insert(inventoryList, Inventory.class); + } + + @Test + void whenIncludeFields_thenOnlyIncludedFieldsAreNotNull() { + Query query = new Query(); + query.fields() + .include("item") + .include("status"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getId()); + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNull(i.getSize()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenIncludeFieldsAndExcludeOtherFields_thenOnlyExcludedFieldsAreNull() { + Query query = new Query(); + query.fields() + .include("item") + .include("status") + .exclude("_id"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNull(i.getId()); + assertNull(i.getSize()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenIncludeAllButExcludeSomeFields_thenOnlyExcludedFieldsAreNull() { + Query query = new Query(); + query.fields() + .exclude("status") + .exclude("inStock"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNull(i.getInStock()); + assertNull(i.getStatus()); + }); + } + + @Test + void whenIncludeEmbeddedFields_thenEmbeddedFieldsAreNotNull() { + Query query = new Query(); + query.fields() + .include("item") + .include("status") + .include("size.uom"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNotNull(i.getSize() + .getUom()); + assertNull(i.getSize() + .getHeight()); + assertNull(i.getSize() + .getWidth()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenExcludeEmbeddedFields_thenEmbeddedFieldsAreNull() { + Query query = new Query(); + query.fields() + .exclude("size.uom"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNull(i.getSize() + .getUom()); + assertNotNull(i.getSize() + .getHeight()); + assertNotNull(i.getSize() + .getWidth()); + assertNotNull(i.getInStock()); + }); + } + + @Test + void whenIncludeEmbeddedFieldsInArray_thenEmbeddedFieldsInArrayAreNotNull() { + Query query = new Query(); + query.fields() + .include("item") + .include("status") + .include("inStock.quantity"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getInStock()); + i.getInStock() + .forEach(stock -> { + assertNull(stock.getWareHouse()); + assertNotNull(stock.getQuantity()); + }); + assertNull(i.getSize()); + }); + } + + @Test + void whenIncludeEmbeddedFieldsSliceInArray_thenArrayLengthEqualToSlice() { + Inventory postcard = new Inventory(); + postcard.setItem("postcard"); + postcard.setStatus("A"); + postcard.setSize(new Size(10.0, 15.25, "cm")); + + InStock firstInStock = new InStock("B", 15); + InStock lastInStock = new InStock("C", 35); + + postcard.setInStock(Arrays.asList(firstInStock, lastInStock)); + + mongoTemplate.save(postcard); + + Query query = new Query(); + query.fields() + .include("item") + .include("status") + .slice("inStock", -1); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getInStock()); + assertEquals(1, i.getInStock() + .size()); + assertNull(i.getSize()); + }); + + InStock stock = inventoryList.stream() + .filter(i -> i.getItem() + .equals("postcard")) + .map(i -> i.getInStock() + .get(0)) + .findFirst() + .orElse(null); + + assertEquals(lastInStock, stock); + } + +} diff --git a/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/RepositoryProjectionUnitTest.java b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/RepositoryProjectionUnitTest.java new file mode 100644 index 0000000000..e8f2d4bf7d --- /dev/null +++ b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/RepositoryProjectionUnitTest.java @@ -0,0 +1,177 @@ +package com.baeldung.projection; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.projection.config.ProjectionConfig; +import com.baeldung.projection.model.InStock; +import com.baeldung.projection.model.Inventory; +import com.baeldung.projection.model.Size; +import com.baeldung.projection.repository.InventoryRepository; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = ProjectionConfig.class) +public class RepositoryProjectionUnitTest extends AbstractTestProjection { + + @Autowired + private InventoryRepository inventoryRepository; + + @BeforeEach + void setup() { + List inventoryList = getInventories(); + + inventoryRepository.saveAll(inventoryList); + } + + @Test + void whenIncludeFields_thenOnlyIncludedFieldsAreNotNull() { + List inventoryList = inventoryRepository.findByStatusIncludeItemAndStatusFields("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getId()); + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNull(i.getSize()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenIncludeFieldsAndExcludeOtherFields_thenOnlyExcludedFieldsAreNull() { + List inventoryList = inventoryRepository.findByStatusIncludeItemAndStatusExcludeIdFields("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNull(i.getId()); + assertNull(i.getSize()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenIncludeAllButExcludeSomeFields_thenOnlyExcludedFieldsAreNull() { + List inventoryList = inventoryRepository.findByStatusIncludeAllButStatusAndStockFields("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNull(i.getInStock()); + assertNull(i.getStatus()); + }); + } + + @Test + void whenIncludeEmbeddedFields_thenEmbeddedFieldsAreNotNull() { + List inventoryList = inventoryRepository.findByStatusIncludeEmbeddedFields("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNotNull(i.getSize() + .getUom()); + assertNull(i.getSize() + .getHeight()); + assertNull(i.getSize() + .getWidth()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenExcludeEmbeddedFields_thenEmbeddedFieldsAreNull() { + List inventoryList = inventoryRepository.findByStatusExcludeEmbeddedFields("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNull(i.getSize() + .getUom()); + assertNotNull(i.getSize() + .getHeight()); + assertNotNull(i.getSize() + .getWidth()); + assertNotNull(i.getInStock()); + }); + } + + @Test + void whenIncludeEmbeddedFieldsInArray_thenEmbeddedFieldsInArrayAreNotNull() { + List inventoryList = inventoryRepository.findByStatusIncludeEmbeddedFieldsInArray("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getInStock()); + i.getInStock() + .forEach(stock -> { + assertNull(stock.getWareHouse()); + assertNotNull(stock.getQuantity()); + }); + assertNull(i.getSize()); + }); + } + + @Test + void whenIncludeEmbeddedFieldsSliceInArray_thenArrayLengthEqualToSlice() { + Inventory postcard = new Inventory(); + postcard.setItem("postcard"); + postcard.setStatus("A"); + postcard.setSize(new Size(10.0, 15.25, "cm")); + + InStock firstInStock = new InStock("B", 15); + InStock lastInStock = new InStock("C", 35); + + postcard.setInStock(Arrays.asList(firstInStock, lastInStock)); + + inventoryRepository.save(postcard); + + List inventoryList = inventoryRepository.findByStatusIncludeEmbeddedFieldsLastElementInArray("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getInStock()); + assertEquals(1, i.getInStock() + .size()); + assertNull(i.getSize()); + }); + + InStock stock = inventoryList.stream() + .filter(i -> i.getItem() + .equals("postcard")) + .map(i -> i.getInStock() + .get(0)) + .findFirst() + .orElse(null); + + assertEquals(lastInStock, stock); + } + +} diff --git a/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/config/ProjectionConfig.java b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/config/ProjectionConfig.java new file mode 100644 index 0000000000..06260c0295 --- /dev/null +++ b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/projection/config/ProjectionConfig.java @@ -0,0 +1,43 @@ +package com.baeldung.projection.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import org.springframework.util.SocketUtils; + +import com.mongodb.client.MongoClients; + +import de.flapdoodle.embed.mongo.MongodExecutable; +import de.flapdoodle.embed.mongo.MongodStarter; +import de.flapdoodle.embed.mongo.config.ImmutableMongodConfig; +import de.flapdoodle.embed.mongo.config.MongodConfig; +import de.flapdoodle.embed.mongo.config.Net; +import de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.process.runtime.Network; + +@Configuration +@ComponentScan(basePackages = "com.baeldung.projection") +@EnableMongoRepositories(basePackages = "com.baeldung.projection.repository") +public class ProjectionConfig { + + private static final String CONNECTION_STRING = "mongodb://%s:%d"; + private static final String HOST = "localhost"; + + @Bean + public MongoTemplate mongoTemplate() throws Exception { + int randomPort = SocketUtils.findAvailableTcpPort(); + + ImmutableMongodConfig mongoDbConfig = MongodConfig.builder() + .version(Version.Main.PRODUCTION) + .net(new Net(HOST, randomPort, Network.localhostIsIPv6())) + .build(); + + MongodStarter starter = MongodStarter.getDefaultInstance(); + MongodExecutable mongodExecutable = starter.prepare(mongoDbConfig); + mongodExecutable.start(); + + return new MongoTemplate(MongoClients.create(String.format(CONNECTION_STRING, HOST, randomPort)), "mongo_auth"); + } +}