From 28cdc0ddc0f259ae00b1657b9251a0f029d33087 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Fri, 27 May 2022 23:55:58 -0300 Subject: [PATCH 01/10] BAEL-5370 - MongoDB Composite Key First Draft. --- .../SpringBootCompositeKeyApplication.java | 15 ++ .../composite/key/dao/CustomerRepository.java | 12 ++ .../composite/key/dao/SaleRepository.java | 12 ++ .../composite/key/dao/TicketRepository.java | 10 ++ .../boot/composite/key/data/Customer.java | 49 ++++++ .../boot/composite/key/data/Sale.java | 38 +++++ .../boot/composite/key/data/Ticket.java | 31 ++++ .../boot/composite/key/data/TicketId.java | 56 +++++++ .../key/service/CustomerService.java | 66 +++++++++ .../composite/key/web/CustomerController.java | 88 +++++++++++ .../boot.composite.key/app.properties | 1 + .../key/CustomerServiceIntegrationTest.java | 140 ++++++++++++++++++ 12 files changed, 518 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/SpringBootCompositeKeyApplication.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/CustomerRepository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/SaleRepository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/TicketRepository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Customer.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Sale.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Ticket.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/TicketId.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/service/CustomerService.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.composite.key/app.properties create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/SpringBootCompositeKeyApplication.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/SpringBootCompositeKeyApplication.java new file mode 100644 index 0000000000..e9f8eab1dd --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/SpringBootCompositeKeyApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.boot.composite.key; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +@SpringBootApplication +@PropertySource("classpath:boot.composite.key/app.properties") +@EnableMongoRepositories(basePackages = { "com.baeldung.boot.composite.key" }) +public class SpringBootCompositeKeyApplication { + public static void main(String... args) { + SpringApplication.run(SpringBootCompositeKeyApplication.class, args); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/CustomerRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/CustomerRepository.java new file mode 100644 index 0000000000..6953a21ddd --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/CustomerRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.boot.composite.key.dao; + +import java.util.Optional; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.composite.key.data.Customer; + +public interface CustomerRepository extends MongoRepository { + + Optional findByStoreIdAndNumber(Long storeId, Long number); +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/SaleRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/SaleRepository.java new file mode 100644 index 0000000000..3caa33d465 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/SaleRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.boot.composite.key.dao; + +import java.util.Optional; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.composite.key.data.Sale; +import com.baeldung.boot.composite.key.data.TicketId; + +public interface SaleRepository extends MongoRepository { + Optional findByTicketId(TicketId ticketId); +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/TicketRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/TicketRepository.java new file mode 100644 index 0000000000..b02ea461d2 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/TicketRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.boot.composite.key.dao; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.composite.key.data.Ticket; +import com.baeldung.boot.composite.key.data.TicketId; + +public interface TicketRepository extends MongoRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Customer.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Customer.java new file mode 100644 index 0000000000..d4bb1ef40c --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Customer.java @@ -0,0 +1,49 @@ +package com.baeldung.boot.composite.key.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.index.CompoundIndex; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +@CompoundIndex(name = "customer_idx", def = "{ 'storeId': 1, 'number': 1 }", unique = true) +public class Customer { + @Id + private String id; + + private Long storeId; + private Long number; + + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Long getStoreId() { + return storeId; + } + + public void setStoreId(Long storeId) { + this.storeId = storeId; + } + + public Long getNumber() { + return number; + } + + public void setNumber(Long number) { + this.number = number; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Sale.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Sale.java new file mode 100644 index 0000000000..a81c91674c --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Sale.java @@ -0,0 +1,38 @@ +package com.baeldung.boot.composite.key.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.index.CompoundIndex; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +@CompoundIndex(name = "sale_idx", def = "{ 'ticketId': 1 }", unique = true) +public class Sale { + @Id + private String id; + + private TicketId ticketId; + private Double value; + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + public TicketId getTicketId() { + return ticketId; + } + + public void setTicketId(TicketId ticketId) { + this.ticketId = ticketId; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Ticket.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Ticket.java new file mode 100644 index 0000000000..7a8ebe1ab3 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Ticket.java @@ -0,0 +1,31 @@ +package com.baeldung.boot.composite.key.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class Ticket { + @Id + private TicketId id; + + private String event; + + public Ticket() { + } + + public TicketId getId() { + return id; + } + + public void setId(TicketId id) { + this.id = id; + } + + public String getEvent() { + return event; + } + + public void setEvent(String event) { + this.event = event; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/TicketId.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/TicketId.java new file mode 100644 index 0000000000..76fbf81391 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/TicketId.java @@ -0,0 +1,56 @@ +package com.baeldung.boot.composite.key.data; + +public class TicketId { + private String venue; + private String date; + + public TicketId() { + } + + public String getVenue() { + return venue; + } + + public void setVenue(String venue) { + this.venue = venue; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((date == null) ? 0 : date.hashCode()); + result = prime * result + ((venue == null) ? 0 : venue.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TicketId other = (TicketId) obj; + if (date == null) { + if (other.date != null) + return false; + } else if (!date.equals(other.date)) + return false; + if (venue == null) { + if (other.venue != null) + return false; + } else if (!venue.equals(other.venue)) + return false; + return true; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/service/CustomerService.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/service/CustomerService.java new file mode 100644 index 0000000000..476209bce9 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/service/CustomerService.java @@ -0,0 +1,66 @@ +package com.baeldung.boot.composite.key.service; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.boot.composite.key.dao.CustomerRepository; +import com.baeldung.boot.composite.key.dao.SaleRepository; +import com.baeldung.boot.composite.key.dao.TicketRepository; +import com.baeldung.boot.composite.key.data.Customer; +import com.baeldung.boot.composite.key.data.Sale; +import com.baeldung.boot.composite.key.data.Ticket; +import com.baeldung.boot.composite.key.data.TicketId; + +@Service +public class CustomerService { + @Autowired + private CustomerRepository customerRepository; + + @Autowired + private TicketRepository ticketRepository; + + @Autowired + private SaleRepository saleRepository; + + public Optional find(TicketId id) { + return ticketRepository.findById(id); + } + + public Ticket insert(Ticket ticket) { + return ticketRepository.insert(ticket); + } + + public Ticket save(Ticket ticket) { + return ticketRepository.save(ticket); + } + + public Optional findCustomerById(String id) { + return customerRepository.findById(id); + } + + public Optional findCustomerByIndex(Long storeId, Long number) { + return customerRepository.findByStoreIdAndNumber(storeId, number); + } + + public Customer insert(Customer customer) { + return customerRepository.insert(customer); + } + + public Customer save(Customer customer) { + return customerRepository.save(customer); + } + + public Sale insert(Sale sale) { + return saleRepository.insert(sale); + } + + public Optional findSaleByTicketId(TicketId ticketId) { + return saleRepository.findByTicketId(ticketId); + } + + public Optional findSaleById(String id) { + return saleRepository.findById(id); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java new file mode 100644 index 0000000000..83afe0ae42 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java @@ -0,0 +1,88 @@ +package com.baeldung.boot.composite.key.web; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.boot.composite.key.data.Customer; +import com.baeldung.boot.composite.key.data.Sale; +import com.baeldung.boot.composite.key.data.Ticket; +import com.baeldung.boot.composite.key.data.TicketId; +import com.baeldung.boot.composite.key.service.CustomerService; + +@RestController +@RequestMapping("/customer") +public class CustomerController { + @Autowired + private CustomerService customerService; + + // @Autowired + // private TicketRepository ticketRepository; + // + // @GetMapping("/ticket") + // public Optional getTicket(TicketId id) { + // return ticketRepository.findById(id); + // } + // + // @PostMapping("/ticket") + // public Ticket postTicket(@RequestBody Ticket ticket) { + // return ticketRepository.insert(ticket); + // } + + @GetMapping("/ticket") + public Optional getTicket(TicketId id) { + return customerService.find(id); + } + + @PostMapping("/ticket") + public Ticket postTicket(@RequestBody Ticket ticket) { + return customerService.insert(ticket); + } + + @PutMapping("/ticket") + public Ticket putTicket(@RequestBody Ticket ticket) { + return customerService.save(ticket); + } + + @GetMapping("/{id}") + public Optional getCustomer(@PathVariable String id) { + return customerService.findCustomerById(id); + } + + @GetMapping("/{storeId}/{number}") + public Optional getCustomerByIndex(@PathVariable Long storeId, @PathVariable Long number) { + return customerService.findCustomerByIndex(storeId, number); + } + + @PostMapping + public Customer postCustomer(@RequestBody Customer customer) { + return customerService.insert(customer); + } + + @PutMapping + public Customer putCustomer(@RequestBody Customer customer) { + return customerService.save(customer); + } + + @PostMapping("/sale") + public Sale postSale(@RequestBody Sale sale) { + return customerService.insert(sale); + } + + @GetMapping("/sale/{id}") + public Optional getSale(@PathVariable String id) { + return customerService.findSaleById(id); + } + + @GetMapping("/sale") + public Optional getSale(TicketId ticketId) { + return customerService.findSaleByTicketId(ticketId); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.composite.key/app.properties b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.composite.key/app.properties new file mode 100644 index 0000000000..a73a94d850 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.composite.key/app.properties @@ -0,0 +1 @@ +spring.data.mongodb.auto-index-creation=true diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java new file mode 100644 index 0000000000..4f779ebf02 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java @@ -0,0 +1,140 @@ +package com.baeldung.boot.composite.key; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import java.util.Optional; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.boot.composite.key.data.Customer; +import com.baeldung.boot.composite.key.data.Ticket; +import com.baeldung.boot.composite.key.data.TicketId; +import com.baeldung.boot.composite.key.service.CustomerService; + +@SpringBootTest +@DirtiesContext +@RunWith(SpringRunner.class) +public class CustomerServiceIntegrationTest { + @Autowired + private CustomerService service; + + private static Ticket ticket; + private static TicketId ticketId; + + @BeforeClass + public static void setup() { + ticket = new Ticket(); + ticket.setEvent("Event A"); + + ticketId = new TicketId(); + ticketId.setDate("2020-01-01"); + ticketId.setVenue("Venue A"); + ticket.setId(ticketId); + } + + @Test + public void givenCompositeId_whenObjectSaved_thenIdMatches() { + Ticket savedTicket = service.insert(ticket); + assertEquals(savedTicket.getId(), ticket.getId()); + } + + @Test + public void givenCompositeId_whenSearchingByIdObject_thenFound() { + Optional optionalTicket = service.find(ticketId); + + assertThat(optionalTicket.isPresent()); + Ticket savedTicket = optionalTicket.get(); + + assertEquals(savedTicket.getId(), ticketId); + } + + @Test + public void givenCompoundUniqueIndex_whenSearchingByGeneratedId_thenFound() { + Customer customer = new Customer(); + customer.setName("Name"); + customer.setNumber(0l); + customer.setStoreId(0l); + + Customer savedCustomer = service.insert(customer); + + Optional optional = service.findCustomerById(savedCustomer.getId()); + + assertThat(optional.isPresent()); + } + + @Test + public void givenCompositeId_whenDupeInsert_thenExceptionIsThrown() { + Ticket ticket = new Ticket(); + ticket.setEvent("C"); + + TicketId ticketId = new TicketId(); + ticketId.setDate("2020-01-01"); + ticketId.setVenue("V"); + ticket.setId(ticketId); + + assertThrows(DuplicateKeyException.class, () -> { + service.insert(ticket); + service.insert(ticket); + }); + } + + @Test + public void givenCompositeId_whenDupeSave_thenObjectUpdated() { + TicketId ticketId = new TicketId(); + ticketId.setDate("2020-01-01"); + ticketId.setVenue("Venue"); + + Ticket ticketA = new Ticket(); + ticketA.setEvent("A"); + ticketA.setId(ticketId); + + service.save(ticketA); + + Ticket ticketB = new Ticket(); + ticketB.setEvent("B"); + ticketB.setId(ticketId); + + Ticket savedTicket = service.save(ticketB); + assertEquals(savedTicket.getEvent(), ticketB.getEvent()); + } + + @Test + public void givenCompoundUniqueIndex_whenDupeInsert_thenExceptionIsThrown() { + Customer customer = new Customer(); + customer.setName("Name"); + customer.setNumber(1l); + customer.setStoreId(2l); + + assertThrows(DuplicateKeyException.class, () -> { + service.insert(customer); + service.insert(customer); + }); + } + + @Test + public void givenCompoundUniqueIndex_whenDupeSave_thenExceptionIsThrown() { + Customer customerA = new Customer(); + customerA.setName("Name A"); + customerA.setNumber(1l); + customerA.setStoreId(2l); + + Customer customerB = new Customer(); + customerB.setName("Name B"); + customerB.setNumber(1l); + customerB.setStoreId(2l); + + assertThrows(DuplicateKeyException.class, () -> { + service.save(customerA); + service.save(customerB); + }); + } +} From 0260f6373e8e148ab32a5ac93239b4258f092ce7 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Fri, 27 May 2022 23:57:12 -0300 Subject: [PATCH 02/10] removing comments --- .../boot/composite/key/web/CustomerController.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java index 83afe0ae42..9e41d13e14 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java @@ -23,19 +23,6 @@ public class CustomerController { @Autowired private CustomerService customerService; - // @Autowired - // private TicketRepository ticketRepository; - // - // @GetMapping("/ticket") - // public Optional getTicket(TicketId id) { - // return ticketRepository.findById(id); - // } - // - // @PostMapping("/ticket") - // public Ticket postTicket(@RequestBody Ticket ticket) { - // return ticketRepository.insert(ticket); - // } - @GetMapping("/ticket") public Optional getTicket(TicketId id) { return customerService.find(id); From 8a75af488ba08fa1e7a4e2fc663ac3d7309c7f3a Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Fri, 3 Jun 2022 10:06:51 -0300 Subject: [PATCH 03/10] BAEL-5370 Test could fail if ran in a different order: givenCompositeId_whenSearchingByIdObject_thenFound --- .../boot/composite/key/data/Ticket.java | 6 +++ .../key/CustomerServiceIntegrationTest.java | 44 +++++++------------ 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Ticket.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Ticket.java index 7a8ebe1ab3..d77b54c513 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Ticket.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Ticket.java @@ -13,6 +13,12 @@ public class Ticket { public Ticket() { } + public Ticket(TicketId id, String event) { + super(); + this.id = id; + this.event = event; + } + public TicketId getId() { return id; } diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java index 4f779ebf02..658be343f1 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.assertThrows; import java.util.Optional; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -27,28 +26,26 @@ public class CustomerServiceIntegrationTest { @Autowired private CustomerService service; - private static Ticket ticket; - private static TicketId ticketId; - - @BeforeClass - public static void setup() { - ticket = new Ticket(); - ticket.setEvent("Event A"); - - ticketId = new TicketId(); - ticketId.setDate("2020-01-01"); - ticketId.setVenue("Venue A"); - ticket.setId(ticketId); - } - @Test public void givenCompositeId_whenObjectSaved_thenIdMatches() { + TicketId ticketId = new TicketId(); + ticketId.setDate("2020-01-01"); + ticketId.setVenue("Venue A"); + + Ticket ticket = new Ticket(ticketId, "Event A"); Ticket savedTicket = service.insert(ticket); + assertEquals(savedTicket.getId(), ticket.getId()); } @Test public void givenCompositeId_whenSearchingByIdObject_thenFound() { + TicketId ticketId = new TicketId(); + ticketId.setDate("2020-01-01"); + ticketId.setVenue("Venue B"); + + service.insert(new Ticket(ticketId, "Event B")); + Optional optionalTicket = service.find(ticketId); assertThat(optionalTicket.isPresent()); @@ -73,13 +70,11 @@ public class CustomerServiceIntegrationTest { @Test public void givenCompositeId_whenDupeInsert_thenExceptionIsThrown() { - Ticket ticket = new Ticket(); - ticket.setEvent("C"); - TicketId ticketId = new TicketId(); ticketId.setDate("2020-01-01"); ticketId.setVenue("V"); - ticket.setId(ticketId); + + Ticket ticket = new Ticket(ticketId, "Event C"); assertThrows(DuplicateKeyException.class, () -> { service.insert(ticket); @@ -93,17 +88,12 @@ public class CustomerServiceIntegrationTest { ticketId.setDate("2020-01-01"); ticketId.setVenue("Venue"); - Ticket ticketA = new Ticket(); - ticketA.setEvent("A"); - ticketA.setId(ticketId); - + Ticket ticketA = new Ticket(ticketId, "A"); service.save(ticketA); - Ticket ticketB = new Ticket(); - ticketB.setEvent("B"); - ticketB.setId(ticketId); - + Ticket ticketB = new Ticket(ticketId, "B"); Ticket savedTicket = service.save(ticketB); + assertEquals(savedTicket.getEvent(), ticketB.getEvent()); } From 793ada0100c3974cba0eca0e3674cdb36de51ace Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Mon, 13 Jun 2022 23:37:28 -0300 Subject: [PATCH 04/10] BAEL-5370 removing compound index related stuff --- .../SpringBootCompositeKeyApplication.java | 2 - .../composite/key/dao/CustomerRepository.java | 12 ----- .../composite/key/dao/SaleRepository.java | 12 ----- .../boot/composite/key/data/Customer.java | 49 ------------------- .../boot/composite/key/data/Sale.java | 38 -------------- .../key/service/CustomerService.java | 38 -------------- .../composite/key/web/CustomerController.java | 38 -------------- .../boot.composite.key/app.properties | 1 - .../key/CustomerServiceIntegrationTest.java | 46 ----------------- 9 files changed, 236 deletions(-) delete mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/CustomerRepository.java delete mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/SaleRepository.java delete mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Customer.java delete mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Sale.java delete mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.composite.key/app.properties diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/SpringBootCompositeKeyApplication.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/SpringBootCompositeKeyApplication.java index e9f8eab1dd..1322adbf77 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/SpringBootCompositeKeyApplication.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/SpringBootCompositeKeyApplication.java @@ -2,11 +2,9 @@ package com.baeldung.boot.composite.key; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.PropertySource; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; @SpringBootApplication -@PropertySource("classpath:boot.composite.key/app.properties") @EnableMongoRepositories(basePackages = { "com.baeldung.boot.composite.key" }) public class SpringBootCompositeKeyApplication { public static void main(String... args) { diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/CustomerRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/CustomerRepository.java deleted file mode 100644 index 6953a21ddd..0000000000 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/CustomerRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.boot.composite.key.dao; - -import java.util.Optional; - -import org.springframework.data.mongodb.repository.MongoRepository; - -import com.baeldung.boot.composite.key.data.Customer; - -public interface CustomerRepository extends MongoRepository { - - Optional findByStoreIdAndNumber(Long storeId, Long number); -} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/SaleRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/SaleRepository.java deleted file mode 100644 index 3caa33d465..0000000000 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/dao/SaleRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.boot.composite.key.dao; - -import java.util.Optional; - -import org.springframework.data.mongodb.repository.MongoRepository; - -import com.baeldung.boot.composite.key.data.Sale; -import com.baeldung.boot.composite.key.data.TicketId; - -public interface SaleRepository extends MongoRepository { - Optional findByTicketId(TicketId ticketId); -} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Customer.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Customer.java deleted file mode 100644 index d4bb1ef40c..0000000000 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Customer.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.baeldung.boot.composite.key.data; - -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.index.CompoundIndex; -import org.springframework.data.mongodb.core.mapping.Document; - -@Document -@CompoundIndex(name = "customer_idx", def = "{ 'storeId': 1, 'number': 1 }", unique = true) -public class Customer { - @Id - private String id; - - private Long storeId; - private Long number; - - private String name; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Long getStoreId() { - return storeId; - } - - public void setStoreId(Long storeId) { - this.storeId = storeId; - } - - public Long getNumber() { - return number; - } - - public void setNumber(Long number) { - this.number = number; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Sale.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Sale.java deleted file mode 100644 index a81c91674c..0000000000 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/data/Sale.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.baeldung.boot.composite.key.data; - -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.index.CompoundIndex; -import org.springframework.data.mongodb.core.mapping.Document; - -@Document -@CompoundIndex(name = "sale_idx", def = "{ 'ticketId': 1 }", unique = true) -public class Sale { - @Id - private String id; - - private TicketId ticketId; - private Double value; - - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - - public TicketId getTicketId() { - return ticketId; - } - - public void setTicketId(TicketId ticketId) { - this.ticketId = ticketId; - } - - public Double getValue() { - return value; - } - - public void setValue(Double value) { - this.value = value; - } -} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/service/CustomerService.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/service/CustomerService.java index 476209bce9..90ca1b758d 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/service/CustomerService.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/service/CustomerService.java @@ -5,25 +5,15 @@ import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.baeldung.boot.composite.key.dao.CustomerRepository; -import com.baeldung.boot.composite.key.dao.SaleRepository; import com.baeldung.boot.composite.key.dao.TicketRepository; -import com.baeldung.boot.composite.key.data.Customer; -import com.baeldung.boot.composite.key.data.Sale; import com.baeldung.boot.composite.key.data.Ticket; import com.baeldung.boot.composite.key.data.TicketId; @Service public class CustomerService { - @Autowired - private CustomerRepository customerRepository; - @Autowired private TicketRepository ticketRepository; - @Autowired - private SaleRepository saleRepository; - public Optional find(TicketId id) { return ticketRepository.findById(id); } @@ -35,32 +25,4 @@ public class CustomerService { public Ticket save(Ticket ticket) { return ticketRepository.save(ticket); } - - public Optional findCustomerById(String id) { - return customerRepository.findById(id); - } - - public Optional findCustomerByIndex(Long storeId, Long number) { - return customerRepository.findByStoreIdAndNumber(storeId, number); - } - - public Customer insert(Customer customer) { - return customerRepository.insert(customer); - } - - public Customer save(Customer customer) { - return customerRepository.save(customer); - } - - public Sale insert(Sale sale) { - return saleRepository.insert(sale); - } - - public Optional findSaleByTicketId(TicketId ticketId) { - return saleRepository.findByTicketId(ticketId); - } - - public Optional findSaleById(String id) { - return saleRepository.findById(id); - } } diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java index 9e41d13e14..4379a46d05 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/composite/key/web/CustomerController.java @@ -4,15 +4,12 @@ import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.boot.composite.key.data.Customer; -import com.baeldung.boot.composite.key.data.Sale; import com.baeldung.boot.composite.key.data.Ticket; import com.baeldung.boot.composite.key.data.TicketId; import com.baeldung.boot.composite.key.service.CustomerService; @@ -37,39 +34,4 @@ public class CustomerController { public Ticket putTicket(@RequestBody Ticket ticket) { return customerService.save(ticket); } - - @GetMapping("/{id}") - public Optional getCustomer(@PathVariable String id) { - return customerService.findCustomerById(id); - } - - @GetMapping("/{storeId}/{number}") - public Optional getCustomerByIndex(@PathVariable Long storeId, @PathVariable Long number) { - return customerService.findCustomerByIndex(storeId, number); - } - - @PostMapping - public Customer postCustomer(@RequestBody Customer customer) { - return customerService.insert(customer); - } - - @PutMapping - public Customer putCustomer(@RequestBody Customer customer) { - return customerService.save(customer); - } - - @PostMapping("/sale") - public Sale postSale(@RequestBody Sale sale) { - return customerService.insert(sale); - } - - @GetMapping("/sale/{id}") - public Optional getSale(@PathVariable String id) { - return customerService.findSaleById(id); - } - - @GetMapping("/sale") - public Optional getSale(TicketId ticketId) { - return customerService.findSaleByTicketId(ticketId); - } } diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.composite.key/app.properties b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.composite.key/app.properties deleted file mode 100644 index a73a94d850..0000000000 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.composite.key/app.properties +++ /dev/null @@ -1 +0,0 @@ -spring.data.mongodb.auto-index-creation=true diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java index 658be343f1..1aee478ad0 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java @@ -14,7 +14,6 @@ import org.springframework.dao.DuplicateKeyException; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.boot.composite.key.data.Customer; import com.baeldung.boot.composite.key.data.Ticket; import com.baeldung.boot.composite.key.data.TicketId; import com.baeldung.boot.composite.key.service.CustomerService; @@ -54,20 +53,6 @@ public class CustomerServiceIntegrationTest { assertEquals(savedTicket.getId(), ticketId); } - @Test - public void givenCompoundUniqueIndex_whenSearchingByGeneratedId_thenFound() { - Customer customer = new Customer(); - customer.setName("Name"); - customer.setNumber(0l); - customer.setStoreId(0l); - - Customer savedCustomer = service.insert(customer); - - Optional optional = service.findCustomerById(savedCustomer.getId()); - - assertThat(optional.isPresent()); - } - @Test public void givenCompositeId_whenDupeInsert_thenExceptionIsThrown() { TicketId ticketId = new TicketId(); @@ -96,35 +81,4 @@ public class CustomerServiceIntegrationTest { assertEquals(savedTicket.getEvent(), ticketB.getEvent()); } - - @Test - public void givenCompoundUniqueIndex_whenDupeInsert_thenExceptionIsThrown() { - Customer customer = new Customer(); - customer.setName("Name"); - customer.setNumber(1l); - customer.setStoreId(2l); - - assertThrows(DuplicateKeyException.class, () -> { - service.insert(customer); - service.insert(customer); - }); - } - - @Test - public void givenCompoundUniqueIndex_whenDupeSave_thenExceptionIsThrown() { - Customer customerA = new Customer(); - customerA.setName("Name A"); - customerA.setNumber(1l); - customerA.setStoreId(2l); - - Customer customerB = new Customer(); - customerB.setName("Name B"); - customerB.setNumber(1l); - customerB.setStoreId(2l); - - assertThrows(DuplicateKeyException.class, () -> { - service.save(customerA); - service.save(customerB); - }); - } } From f1259c2a4d717dc2e3c16f26eb6cae1c065d70b0 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Fri, 17 Jun 2022 12:01:44 -0300 Subject: [PATCH 05/10] removing first insert from assertThrows --- .../boot/composite/key/CustomerServiceIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java index 1aee478ad0..af310ab29e 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/composite/key/CustomerServiceIntegrationTest.java @@ -60,10 +60,10 @@ public class CustomerServiceIntegrationTest { ticketId.setVenue("V"); Ticket ticket = new Ticket(ticketId, "Event C"); + service.insert(ticket); assertThrows(DuplicateKeyException.class, () -> { service.insert(ticket); - service.insert(ticket); }); } From e0a7591f9defa207018816003a8b99e192a9b5fe Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Sun, 19 Jun 2022 16:32:10 -0300 Subject: [PATCH 06/10] first draft --- .../SpringBootUniqueFieldApplication.java | 15 +++ .../unique/field/dao/AssetRepository.java | 8 ++ .../unique/field/dao/CompanyRepository.java | 11 ++ .../unique/field/dao/Customer2Repository.java | 8 ++ .../unique/field/dao/CustomerRepository.java | 11 ++ .../boot/unique/field/dao/SaleRepository.java | 12 ++ .../boot/unique/field/data/Asset.java | 29 +++++ .../boot/unique/field/data/Company.java | 40 +++++++ .../boot/unique/field/data/Customer.java | 57 +++++++++ .../boot/unique/field/data/Customer2.java | 47 ++++++++ .../baeldung/boot/unique/field/data/Sale.java | 36 ++++++ .../boot/unique/field/data/SaleId.java | 22 ++++ .../field/web/UniqueFieldController.java | 93 +++++++++++++++ .../boot.unique.field/app.properties | 1 + .../field/UniqueFieldIntegrationTest.java | 112 ++++++++++++++++++ 15 files changed, 502 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/SpringBootUniqueFieldApplication.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/AssetRepository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/CompanyRepository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/Customer2Repository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/CustomerRepository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/SaleRepository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Asset.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Company.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer2.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Sale.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/SaleId.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/web/UniqueFieldController.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.unique.field/app.properties create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/unique/field/UniqueFieldIntegrationTest.java diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/SpringBootUniqueFieldApplication.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/SpringBootUniqueFieldApplication.java new file mode 100644 index 0000000000..648ecd4dfb --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/SpringBootUniqueFieldApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.boot.unique.field; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +@SpringBootApplication +@PropertySource("classpath:boot.unique.field/app.properties") +@EnableMongoRepositories(basePackages = { "com.baeldung.boot.unique.field" }) +public class SpringBootUniqueFieldApplication { + public static void main(String... args) { + SpringApplication.run(SpringBootUniqueFieldApplication.class, args); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/AssetRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/AssetRepository.java new file mode 100644 index 0000000000..9adca8b4bd --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/AssetRepository.java @@ -0,0 +1,8 @@ +package com.baeldung.boot.unique.field.dao; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.unique.field.data.Asset; + +public interface AssetRepository extends MongoRepository { +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/CompanyRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/CompanyRepository.java new file mode 100644 index 0000000000..718e284efe --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/CompanyRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.boot.unique.field.dao; + +import java.util.Optional; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.unique.field.data.Company; + +public interface CompanyRepository extends MongoRepository { + Optional findByEmail(String email); +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/Customer2Repository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/Customer2Repository.java new file mode 100644 index 0000000000..6afe004609 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/Customer2Repository.java @@ -0,0 +1,8 @@ +package com.baeldung.boot.unique.field.dao; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.unique.field.data.Customer2; + +public interface Customer2Repository extends MongoRepository { +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/CustomerRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/CustomerRepository.java new file mode 100644 index 0000000000..f6e5b54470 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/CustomerRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.boot.unique.field.dao; + +import java.util.Optional; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.unique.field.data.Customer; + +public interface CustomerRepository extends MongoRepository { + Optional findByStoreIdAndNumber(Long storeId, Long number); +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/SaleRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/SaleRepository.java new file mode 100644 index 0000000000..8547a5ab76 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/SaleRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.boot.unique.field.dao; + +import java.util.Optional; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.unique.field.data.Sale; +import com.baeldung.boot.unique.field.data.SaleId; + +public interface SaleRepository extends MongoRepository { + Optional findBySaleId(SaleId id); +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Asset.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Asset.java new file mode 100644 index 0000000000..9652691a8b --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Asset.java @@ -0,0 +1,29 @@ +package com.baeldung.boot.unique.field.data; + +import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class Asset { + @Indexed(unique = true) + private String name; + + @Indexed(unique = true) + private Integer number; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Company.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Company.java new file mode 100644 index 0000000000..31b4cf0588 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Company.java @@ -0,0 +1,40 @@ +package com.baeldung.boot.unique.field.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class Company { + @Id + private String id; + + private String name; + + @Indexed(unique = true) + private String email; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer.java new file mode 100644 index 0000000000..d1459dc663 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer.java @@ -0,0 +1,57 @@ +package com.baeldung.boot.unique.field.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.index.CompoundIndex; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +@CompoundIndex(name = "customer_idx", def = "{ 'storeId': 1, 'number': 1 }", unique = true) +public class Customer { + @Id + private String id; + + private Long storeId; + + private Long number; + + private String name; + + public Customer() { + } + + public Customer(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Long getStoreId() { + return storeId; + } + + public void setStoreId(Long storeId) { + this.storeId = storeId; + } + + public Long getNumber() { + return number; + } + + public void setNumber(Long number) { + this.number = number; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer2.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer2.java new file mode 100644 index 0000000000..523a0a9841 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer2.java @@ -0,0 +1,47 @@ +package com.baeldung.boot.unique.field.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.index.CompoundIndex; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +@CompoundIndex(def = "{ 'storeId': 1, 'number': 1 }", unique = true) +public class Customer2 { + @Id + private Long storeId; + + private Long number; + + private String name; + + public Customer2() { + } + + public Customer2(String name) { + this.name = name; + } + + public Long getStoreId() { + return storeId; + } + + public void setStoreId(Long storeId) { + this.storeId = storeId; + } + + public Long getNumber() { + return number; + } + + public void setNumber(Long number) { + this.number = number; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Sale.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Sale.java new file mode 100644 index 0000000000..3d0a549575 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Sale.java @@ -0,0 +1,36 @@ +package com.baeldung.boot.unique.field.data; + +import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class Sale { + @Indexed(unique = true) + private SaleId saleId; + + private Double value; + + public Sale() { + } + + public Sale(SaleId saleId) { + super(); + this.saleId = saleId; + } + + public SaleId getSaleId() { + return saleId; + } + + public void setSaleId(SaleId saleId) { + this.saleId = saleId; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/SaleId.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/SaleId.java new file mode 100644 index 0000000000..69a5c5a561 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/SaleId.java @@ -0,0 +1,22 @@ +package com.baeldung.boot.unique.field.data; + +public class SaleId { + private Long item; + private String date; + + public Long getItem() { + return item; + } + + public void setItem(Long item) { + this.item = item; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/web/UniqueFieldController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/web/UniqueFieldController.java new file mode 100644 index 0000000000..8ac00c497f --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/web/UniqueFieldController.java @@ -0,0 +1,93 @@ +package com.baeldung.boot.unique.field.web; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.boot.unique.field.dao.AssetRepository; +import com.baeldung.boot.unique.field.dao.CompanyRepository; +import com.baeldung.boot.unique.field.dao.Customer2Repository; +import com.baeldung.boot.unique.field.dao.CustomerRepository; +import com.baeldung.boot.unique.field.dao.SaleRepository; +import com.baeldung.boot.unique.field.data.Asset; +import com.baeldung.boot.unique.field.data.Company; +import com.baeldung.boot.unique.field.data.Customer; +import com.baeldung.boot.unique.field.data.Customer2; +import com.baeldung.boot.unique.field.data.Sale; +import com.baeldung.boot.unique.field.data.SaleId; + +@RestController +@RequestMapping("/unique-field") +public class UniqueFieldController { + @Autowired + private SaleRepository saleRepo; + + @Autowired + private CompanyRepository companyRepo; + + @Autowired + private CustomerRepository customerRepo; + + @Autowired + private Customer2Repository customer2Repo; + + @Autowired + private AssetRepository assetRepo; + + @PostMapping("/sale") + public Sale post(@RequestBody Sale sale) { + return saleRepo.insert(sale); + } + + @GetMapping("/sale") + public Optional getSale(SaleId id) { + return saleRepo.findBySaleId(id); + } + + @PostMapping("/company") + public Company post(@RequestBody Company company) { + return companyRepo.insert(company); + } + + @PutMapping("/company") + public Company put(@RequestBody Company company) { + return companyRepo.save(company); + } + + @GetMapping("/company/{id}") + public Optional getCompany(@PathVariable String id) { + return companyRepo.findById(id); + } + + @PostMapping("/customer") + public Customer post(@RequestBody Customer customer) { + return customerRepo.insert(customer); + } + + @PostMapping("/customer2") + public Customer2 post(@RequestBody Customer2 customer) { + return customer2Repo.insert(customer); + } + + @GetMapping("/customer/{id}") + public Optional getCustomer(@PathVariable String id) { + return customerRepo.findById(id); + } + + @PostMapping("/asset") + public Asset post(@RequestBody Asset asset) { + return assetRepo.insert(asset); + } + + @GetMapping("/asset/{id}") + public Optional getAsset(@PathVariable String id) { + return assetRepo.findById(id); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.unique.field/app.properties b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.unique.field/app.properties new file mode 100644 index 0000000000..a73a94d850 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.unique.field/app.properties @@ -0,0 +1 @@ +spring.data.mongodb.auto-index-creation=true diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/unique/field/UniqueFieldIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/unique/field/UniqueFieldIntegrationTest.java new file mode 100644 index 0000000000..c18a877b79 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/unique/field/UniqueFieldIntegrationTest.java @@ -0,0 +1,112 @@ +package com.baeldung.boot.unique.field; + +import static org.junit.Assert.assertThrows; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.boot.unique.field.dao.AssetRepository; +import com.baeldung.boot.unique.field.dao.CompanyRepository; +import com.baeldung.boot.unique.field.dao.CustomerRepository; +import com.baeldung.boot.unique.field.dao.SaleRepository; +import com.baeldung.boot.unique.field.data.Asset; +import com.baeldung.boot.unique.field.data.Company; +import com.baeldung.boot.unique.field.data.Customer; +import com.baeldung.boot.unique.field.data.Sale; +import com.baeldung.boot.unique.field.data.SaleId; + +@SpringBootTest +@DirtiesContext +@RunWith(SpringRunner.class) +public class UniqueFieldIntegrationTest { + @Autowired + private SaleRepository saleRepo; + + @Autowired + private CompanyRepository companyRepo; + + @Autowired + private CustomerRepository customerRepo; + + @Autowired + private AssetRepository assetRepo; + + @Test + public void givenMultipleIndexes_whenAnyFieldDupe_thenExceptionIsThrown() { + Asset a = new Asset(); + a.setName("Name"); + a.setNumber(1); + + assetRepo.insert(a); + + Asset b = new Asset(); + b.setName("Name"); + b.setNumber(2); + assertThrows(DuplicateKeyException.class, () -> { + assetRepo.insert(b); + }); + + Asset c = new Asset(); + c.setName("Other"); + c.setNumber(1); + assertThrows(DuplicateKeyException.class, () -> { + assetRepo.insert(c); + }); + } + + @Test + public void givenUniqueIndex_whenInsertingDupe_thenExceptionIsThrown() { + Company a = new Company(); + a.setName("Name"); + a.setEmail("a@mail.com"); + + companyRepo.insert(a); + + Company b = new Company(); + b.setName("Other"); + b.setEmail("a@mail.com"); + assertThrows(DuplicateKeyException.class, () -> { + companyRepo.insert(b); + }); + } + + @Test + public void givenCompoundIndex_whenDupeInsert_thenExceptionIsThrown() { + Customer customerA = new Customer("Name A"); + customerA.setNumber(1l); + customerA.setStoreId(2l); + + Customer customerB = new Customer("Name B"); + customerB.setNumber(1l); + customerB.setStoreId(2l); + + customerRepo.insert(customerA); + + assertThrows(DuplicateKeyException.class, () -> { + customerRepo.insert(customerB); + }); + } + + @Test + public void givenCustomTypeIndex_whenInsertingDupe_thenExceptionIsThrown() { + SaleId id = new SaleId(); + id.setDate("2022-06-15"); + id.setItem(1L); + + Sale a = new Sale(id); + a.setValue(53.94); + + saleRepo.insert(a); + + Sale b = new Sale(id); + b.setValue(100.00); + assertThrows(DuplicateKeyException.class, () -> { + saleRepo.insert(b); + }); + } +} From 3ae97db187f253b5773d120b89601e34b57e9630 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Sun, 19 Jun 2022 16:35:36 -0300 Subject: [PATCH 07/10] removing Customer2 --- .../unique/field/dao/Customer2Repository.java | 8 ---- .../boot/unique/field/data/Customer2.java | 47 ------------------- .../field/web/UniqueFieldController.java | 10 ---- 3 files changed, 65 deletions(-) delete mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/Customer2Repository.java delete mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer2.java diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/Customer2Repository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/Customer2Repository.java deleted file mode 100644 index 6afe004609..0000000000 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/dao/Customer2Repository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.boot.unique.field.dao; - -import org.springframework.data.mongodb.repository.MongoRepository; - -import com.baeldung.boot.unique.field.data.Customer2; - -public interface Customer2Repository extends MongoRepository { -} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer2.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer2.java deleted file mode 100644 index 523a0a9841..0000000000 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/data/Customer2.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.baeldung.boot.unique.field.data; - -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.index.CompoundIndex; -import org.springframework.data.mongodb.core.mapping.Document; - -@Document -@CompoundIndex(def = "{ 'storeId': 1, 'number': 1 }", unique = true) -public class Customer2 { - @Id - private Long storeId; - - private Long number; - - private String name; - - public Customer2() { - } - - public Customer2(String name) { - this.name = name; - } - - public Long getStoreId() { - return storeId; - } - - public void setStoreId(Long storeId) { - this.storeId = storeId; - } - - public Long getNumber() { - return number; - } - - public void setNumber(Long number) { - this.number = number; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/web/UniqueFieldController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/web/UniqueFieldController.java index 8ac00c497f..716977edd4 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/web/UniqueFieldController.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/unique/field/web/UniqueFieldController.java @@ -13,13 +13,11 @@ import org.springframework.web.bind.annotation.RestController; import com.baeldung.boot.unique.field.dao.AssetRepository; import com.baeldung.boot.unique.field.dao.CompanyRepository; -import com.baeldung.boot.unique.field.dao.Customer2Repository; import com.baeldung.boot.unique.field.dao.CustomerRepository; import com.baeldung.boot.unique.field.dao.SaleRepository; import com.baeldung.boot.unique.field.data.Asset; import com.baeldung.boot.unique.field.data.Company; import com.baeldung.boot.unique.field.data.Customer; -import com.baeldung.boot.unique.field.data.Customer2; import com.baeldung.boot.unique.field.data.Sale; import com.baeldung.boot.unique.field.data.SaleId; @@ -35,9 +33,6 @@ public class UniqueFieldController { @Autowired private CustomerRepository customerRepo; - @Autowired - private Customer2Repository customer2Repo; - @Autowired private AssetRepository assetRepo; @@ -71,11 +66,6 @@ public class UniqueFieldController { return customerRepo.insert(customer); } - @PostMapping("/customer2") - public Customer2 post(@RequestBody Customer2 customer) { - return customer2Repo.insert(customer); - } - @GetMapping("/customer/{id}") public Optional getCustomer(@PathVariable String id) { return customerRepo.findById(id); From e5ad2b045b0cc081285e58913e3b0f8bead7cf6e Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Mon, 11 Jul 2022 16:39:59 -0300 Subject: [PATCH 08/10] first draft --- .../count/SpringBootCountApplication.java | 13 ++ .../boot/count/dao/CarRepository.java | 16 +++ .../com/baeldung/boot/count/data/Car.java | 32 +++++ .../boot/count/service/CountCarService.java | 69 ++++++++++ .../boot/count/web/CarController.java | 79 ++++++++++++ .../CountCarServiceIntegrationTest.java | 118 ++++++++++++++++++ 6 files changed, 327 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/SpringBootCountApplication.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/dao/CarRepository.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/data/Car.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/service/CountCarService.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/web/CarController.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/count/service/CountCarServiceIntegrationTest.java diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/SpringBootCountApplication.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/SpringBootCountApplication.java new file mode 100644 index 0000000000..bb7351383c --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/SpringBootCountApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.boot.count; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +@SpringBootApplication +@EnableMongoRepositories(basePackages = { "com.baeldung.boot.count" }) +public class SpringBootCountApplication { + public static void main(String... args) { + SpringApplication.run(SpringBootCountApplication.class, args); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/dao/CarRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/dao/CarRepository.java new file mode 100644 index 0000000000..b03298852e --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/dao/CarRepository.java @@ -0,0 +1,16 @@ +package com.baeldung.boot.count.dao; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; + +import com.baeldung.boot.count.data.Car; + +public interface CarRepository extends MongoRepository { + @Query(value = "{brand: ?0}", count = true) + public long countBrand(String brand); + + Long countByBrand(String brand); + + @Query(value = "{}", count = true) + Long countWithAnnotation(); +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/data/Car.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/data/Car.java new file mode 100644 index 0000000000..55c26c1de4 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/data/Car.java @@ -0,0 +1,32 @@ +package com.baeldung.boot.count.data; + +import org.springframework.data.mongodb.core.mapping.Document; +@Document +public class Car { + private String name; + + private String brand; + + public Car() { + } + + public Car(String brand) { + this.brand = brand; + } + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + this.brand = brand; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/service/CountCarService.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/service/CountCarService.java new file mode 100644 index 0000000000..d4685847fb --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/service/CountCarService.java @@ -0,0 +1,69 @@ +package com.baeldung.boot.count.service; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Example; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Service; + +import com.baeldung.boot.count.dao.CarRepository; +import com.baeldung.boot.count.data.Car; + +@Service +public class CountCarService { + + @Autowired + private CarRepository repo; + + @Autowired + private MongoTemplate mongo; + + public List findCars() { + return repo.findAll(); + } + + public Optional findCar(String id) { + return repo.findById(id); + } + + public Car insertCar(Car item) { + return repo.insert(item); + } + + public long getCountWithQueryAnnotation() { + return repo.countWithAnnotation(); + } + + public long getCountWithCrudRepository() { + return repo.count(); + } + + public long getCountBrandWithQueryMethod(String brand) { + return repo.countByBrand(brand); + } + + public long getCountWithExample(Car item) { + return repo.count(Example.of(item)); + } + + public long getCountWithExampleCriteria(Car item) { + Query query = new Query(); + query.addCriteria(Criteria.byExample(item)); + return mongo.count(query, Car.class); + } + + public long getCountBrandWithQueryAnnotation(String brand) { + return repo.countBrand(brand); + } + + public long getCountBrandWithCriteria(String brand) { + Query query = new Query(); + query.addCriteria(Criteria.where("brand") + .is(brand)); + return mongo.count(query, Car.class); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/web/CarController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/web/CarController.java new file mode 100644 index 0000000000..bc5d6dff9d --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/web/CarController.java @@ -0,0 +1,79 @@ +package com.baeldung.boot.count.web; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Example; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.boot.count.dao.CarRepository; +import com.baeldung.boot.count.data.Car; + +@RestController +@RequestMapping("/car") +public class CarController { + @Autowired + private CarRepository carRepo; + + @Autowired + private MongoTemplate mongo; + + @GetMapping("/{id}") + public Optional getCar(@PathVariable String id) { + return carRepo.findById(id); + } + + @PostMapping + public Car postCar(@RequestBody Car item) { + return carRepo.insert(item); + } + + @GetMapping("/count/{brand}") + public Long getCountCarBrand(@PathVariable String brand) { + return carRepo.countByBrand(brand); + } + + @GetMapping("/count2/{brand}") + public Long getCountCarBrand2(@PathVariable String brand) { + return carRepo.countBrand(brand); + } + + @GetMapping("/count") + public Long getCountCar() { + return carRepo.countWithAnnotation(); + } + + @GetMapping("/count2") + public Long getCountCar2() { + // default do repo + return carRepo.count(); + } + + @PostMapping("/count") + public Long postCount(@RequestBody Car item) { + return carRepo.count(Example.of(item)); + } + + @PostMapping("/count/criteria") + public Long postCountCriteria(@RequestBody Car item) { + Query query = new Query(); + query.addCriteria(Criteria.byExample(item)); + return mongo.count(query, Car.class); + } + + @GetMapping("/count/criteria/{brand}") + public Long getCountCarCriteria(@PathVariable String brand) { + Query query = new Query(); + query.addCriteria(Criteria.where("brand") + .is(brand)); + return mongo.count(query, Car.class); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/count/service/CountCarServiceIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/count/service/CountCarServiceIntegrationTest.java new file mode 100644 index 0000000000..421ecd3a34 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/count/service/CountCarServiceIntegrationTest.java @@ -0,0 +1,118 @@ +package com.baeldung.boot.count.service; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.boot.count.data.Car; + +@SpringBootTest +@DirtiesContext +@RunWith(SpringRunner.class) +public class CountCarServiceIntegrationTest { + @Autowired + private CountCarService service; + + Car car1 = new Car("B-A"); + + @Before + public void init() { + service.insertCar(car1); + service.insertCar(new Car("B-B")); + service.insertCar(new Car("B-C")); + } + + @Test + public void givenAllDocs_whenQueryAnnotationCount_thenCountEqualsSize() { + List all = service.findCars(); + + long count = service.getCountWithQueryAnnotation(); + + assertEquals(count, all.size()); + } + + @Test + public void givenAllDocs_whenCrudRepositoryCount_thenCountEqualsSize() { + List all = service.findCars(); + + long count = service.getCountWithCrudRepository(); + + assertEquals(count, all.size()); + } + + @Test + public void givenFilteredDocs_whenCriteriaCountByBrand_thenCountEqualsSize() { + String filter = "B-A"; + long all = service.findCars() + .stream() + .filter(car -> car.getBrand() + .equals(filter)) + .count(); + + long count = service.getCountBrandWithCriteria(filter); + + assertEquals(count, all); + } + + @Test + public void givenQueryAnnotation_whenCountingByBrand_thenCountEqualsSize() { + String filter = "B-A"; + long all = service.findCars() + .stream() + .filter(car -> car.getBrand() + .equals(filter)) + .count(); + + long count = service.getCountBrandWithQueryAnnotation(filter); + + assertEquals(count, all); + } + + @Test + public void givenFilteredDocs_whenQueryMethodCountByBrand_thenCountEqualsSize() { + String filter = "B-A"; + long all = service.findCars() + .stream() + .filter(car -> car.getBrand() + .equals(filter)) + .count(); + + long count = service.getCountBrandWithQueryMethod(filter); + + assertEquals(count, all); + } + + @Test + public void givenFilteredDocs_whenExampleCount_thenCountEqualsSize() { + long all = service.findCars() + .stream() + .filter(car -> car.getBrand() + .equals(car1.getBrand())) + .count(); + + long count = service.getCountWithExample(car1); + + assertEquals(count, all); + } + + @Test + public void givenFilteredDocs_whenExampleCriteriaCount_thenCountEqualsSize() { + long all = service.findCars() + .stream() + .filter(car -> car.getBrand() + .equals(car1.getBrand())) + .count(); + + long count = service.getCountWithExampleCriteria(car1); + + assertEquals(count, all); + } +} From 8982fdcf737c3e973202ac4474a1c3002f42262d Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Fri, 15 Jul 2022 13:17:12 -0300 Subject: [PATCH 09/10] adjustments * removed controlled * fixed formatting on Car --- .../com/baeldung/boot/count/data/Car.java | 1 + .../boot/count/web/CarController.java | 79 ------------------- 2 files changed, 1 insertion(+), 79 deletions(-) delete mode 100644 persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/web/CarController.java diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/data/Car.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/data/Car.java index 55c26c1de4..42b80d70b0 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/data/Car.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/data/Car.java @@ -1,6 +1,7 @@ package com.baeldung.boot.count.data; import org.springframework.data.mongodb.core.mapping.Document; + @Document public class Car { private String name; diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/web/CarController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/web/CarController.java deleted file mode 100644 index bc5d6dff9d..0000000000 --- a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/count/web/CarController.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.baeldung.boot.count.web; - -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Example; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.baeldung.boot.count.dao.CarRepository; -import com.baeldung.boot.count.data.Car; - -@RestController -@RequestMapping("/car") -public class CarController { - @Autowired - private CarRepository carRepo; - - @Autowired - private MongoTemplate mongo; - - @GetMapping("/{id}") - public Optional getCar(@PathVariable String id) { - return carRepo.findById(id); - } - - @PostMapping - public Car postCar(@RequestBody Car item) { - return carRepo.insert(item); - } - - @GetMapping("/count/{brand}") - public Long getCountCarBrand(@PathVariable String brand) { - return carRepo.countByBrand(brand); - } - - @GetMapping("/count2/{brand}") - public Long getCountCarBrand2(@PathVariable String brand) { - return carRepo.countBrand(brand); - } - - @GetMapping("/count") - public Long getCountCar() { - return carRepo.countWithAnnotation(); - } - - @GetMapping("/count2") - public Long getCountCar2() { - // default do repo - return carRepo.count(); - } - - @PostMapping("/count") - public Long postCount(@RequestBody Car item) { - return carRepo.count(Example.of(item)); - } - - @PostMapping("/count/criteria") - public Long postCountCriteria(@RequestBody Car item) { - Query query = new Query(); - query.addCriteria(Criteria.byExample(item)); - return mongo.count(query, Car.class); - } - - @GetMapping("/count/criteria/{brand}") - public Long getCountCarCriteria(@PathVariable String brand) { - Query query = new Query(); - query.addCriteria(Criteria.where("brand") - .is(brand)); - return mongo.count(query, Car.class); - } -} From e12f0d064f3e7496221d16393477b6794c15fed4 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Mon, 25 Jul 2022 12:27:02 -0300 Subject: [PATCH 10/10] JAVA-13615 GitHub Issue: The code for A* is in the src/test/java directory, not the src/main/java directory --- .../{test => main}/java/com/baeldung/algorithms/astar/Graph.java | 0 .../java/com/baeldung/algorithms/astar/GraphNode.java | 0 .../java/com/baeldung/algorithms/astar/RouteFinder.java | 0 .../java/com/baeldung/algorithms/astar/RouteNode.java | 0 .../{test => main}/java/com/baeldung/algorithms/astar/Scorer.java | 0 .../baeldung/algorithms/astar/underground/HaversineScorer.java | 0 .../java/com/baeldung/algorithms/astar/underground/Station.java | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename algorithms-modules/algorithms-miscellaneous-2/src/{test => main}/java/com/baeldung/algorithms/astar/Graph.java (100%) rename algorithms-modules/algorithms-miscellaneous-2/src/{test => main}/java/com/baeldung/algorithms/astar/GraphNode.java (100%) rename algorithms-modules/algorithms-miscellaneous-2/src/{test => main}/java/com/baeldung/algorithms/astar/RouteFinder.java (100%) rename algorithms-modules/algorithms-miscellaneous-2/src/{test => main}/java/com/baeldung/algorithms/astar/RouteNode.java (100%) rename algorithms-modules/algorithms-miscellaneous-2/src/{test => main}/java/com/baeldung/algorithms/astar/Scorer.java (100%) rename algorithms-modules/algorithms-miscellaneous-2/src/{test => main}/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java (100%) rename algorithms-modules/algorithms-miscellaneous-2/src/{test => main}/java/com/baeldung/algorithms/astar/underground/Station.java (100%) diff --git a/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Graph.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/Graph.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Graph.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/Graph.java diff --git a/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/GraphNode.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/GraphNode.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/GraphNode.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/GraphNode.java diff --git a/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteFinder.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/RouteFinder.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteFinder.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/RouteFinder.java diff --git a/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteNode.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/RouteNode.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteNode.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/RouteNode.java diff --git a/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Scorer.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/Scorer.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Scorer.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/Scorer.java diff --git a/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java diff --git a/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/Station.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/underground/Station.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/Station.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/astar/underground/Station.java