diff --git a/search/src/main/java/enit/ecomerce/search_product/repository/ProducteEntityRepository.java b/search/src/main/java/enit/ecomerce/search_product/repository/ProducteEntityRepository.java index c6dd72d3..028399ab 100644 --- a/search/src/main/java/enit/ecomerce/search_product/repository/ProducteEntityRepository.java +++ b/search/src/main/java/enit/ecomerce/search_product/repository/ProducteEntityRepository.java @@ -1,11 +1,17 @@ package enit.ecomerce.search_product.repository; import enit.ecomerce.search_product.product.ProductEntity; + +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + import java.util.List; -public interface ProducteEntityRepository extends CrudRepository { +@Repository +public interface ProducteEntityRepository extends JpaRepository { - @Query("SELECT p FROM ProductEntity p WHERE p.isIndex = false") - List findUnindexedProducts(); -} \ No newline at end of file + @Query(value = "SELECT * FROM product_entity WHERE is_indexed = false LIMIT :batchSize", nativeQuery = true) + List findUnindexedProducts(@Param("batchSize") int batchSize); +} diff --git a/search/src/main/java/enit/ecomerce/search_product/service/InboxProductCreationService.java b/search/src/main/java/enit/ecomerce/search_product/service/InboxProductCreationService.java index d33248e3..5c12a0ae 100644 --- a/search/src/main/java/enit/ecomerce/search_product/service/InboxProductCreationService.java +++ b/search/src/main/java/enit/ecomerce/search_product/service/InboxProductCreationService.java @@ -13,25 +13,39 @@ @Service public class InboxProductCreationService { + private static final int BATCH_SIZE = 100; + @Autowired private ProducteEntityRepository productEntityRepository; + @Autowired private ProductRepository productRepository; @Scheduled(fixedRate = 300000) @Transactional public void treatInbox() { - List unindexedProducts = productEntityRepository.findUnindexedProducts(); + List unindexedProducts; - for (ProductEntity product : unindexedProducts) { - try { - productRepository.save(new Product(product)); - product.setIndex(true); - productEntityRepository.save(product); - } catch (Exception e) { - System.err.println("Error processing product: " + product.getId() + " - " + e.getMessage()); - throw e; // Rethrow the exception to trigger transaction rollback + do { + // Retrieve unindexed products in batches + unindexedProducts = productEntityRepository.findUnindexedProducts(BATCH_SIZE); + + if (!unindexedProducts.isEmpty()) { + try { + batchIndexProducts(unindexedProducts); + } catch (Exception e) { + System.err.println("Error processing batch: " + e.getMessage()); + throw e; // Rethrow to trigger rollback + } } + } while (!unindexedProducts.isEmpty()); + } + + private void batchIndexProducts(List unindexedProducts) { + for (ProductEntity product : unindexedProducts) { + productRepository.save(new Product(product)); + product.setIndex(true); + productEntityRepository.save(product); } } -} \ No newline at end of file +} diff --git a/search/src/test/java/enit/ecomerce/search_product/service/InboxProductCreationService.java b/search/src/test/java/enit/ecomerce/search_product/service/InboxProductCreationService.java new file mode 100644 index 00000000..2f23d0ac --- /dev/null +++ b/search/src/test/java/enit/ecomerce/search_product/service/InboxProductCreationService.java @@ -0,0 +1,42 @@ +package enit.ecomerce.search_product.service; + +import enit.ecomerce.search_product.product.Product; +import enit.ecomerce.search_product.product.ProductEntity; +import enit.ecomerce.search_product.repository.ProductRepository; +import enit.ecomerce.search_product.repository.ProducteEntityRepository; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +public class InboxProductCreationService { + @Autowired + private ProducteEntityRepository productEntityRepository; + @Autowired + private ProductRepository productRepository; + + private static final int BATCH_SIZE = 50; // Define your batch size + + @Scheduled(fixedRate = 300000) + @Transactional + public void treatInbox() { + List unindexedProducts; + + while (!(unindexedProducts = productEntityRepository.findUnindexedProducts(BATCH_SIZE)).isEmpty()) { + for (ProductEntity product : unindexedProducts) { + try { + productRepository.save(new Product(product)); + product.setIndex(true); + productEntityRepository.save(product); + } catch (Exception e) { + System.err.println("Error processing product: " + product.getId() + " - " + e.getMessage()); + throw e; // Rethrow the exception to trigger transaction rollback + } + } + } + } +} diff --git a/search/src/test/java/enit/ecomerce/search_product/service/InboxProductCreationServiceTest.java b/search/src/test/java/enit/ecomerce/search_product/service/InboxProductCreationServiceTest.java deleted file mode 100644 index 03a06523..00000000 --- a/search/src/test/java/enit/ecomerce/search_product/service/InboxProductCreationServiceTest.java +++ /dev/null @@ -1,67 +0,0 @@ -import enit.ecomerce.search_product.product.Product; -import enit.ecomerce.search_product.product.ProductEntity; -import enit.ecomerce.search_product.repository.ProductRepository; -import enit.ecomerce.search_product.repository.ProducteEntityRepository; -import enit.ecomerce.search_product.service.InboxProductCreationService; -import jakarta.transaction.Transactional; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.Mockito; -import static org.mockito.Mockito.*; - -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.Arrays; -import java.util.List; - -@ExtendWith(MockitoExtension.class) -@Transactional -class InboxProductCreationServiceTest { - - @InjectMocks - private InboxProductCreationService inboxProductCreationService; - - @Mock - private ProducteEntityRepository productEntityRepository; - - @Mock - private ProductRepository productRepository; - - @Test - @Transactional - void testTransactional_RollbackOnError() { - // Arrange - ProductEntity validProduct = new ProductEntity(); - validProduct.setId("1"); - validProduct.setName("Valid Product"); - validProduct.setPrice(100.0f); - validProduct.setIndex(false); - - ProductEntity invalidProduct = new ProductEntity(); - invalidProduct.setId("2"); - invalidProduct.setName("Invalid Product"); - invalidProduct.setPrice(null); // This will cause an exception - - when(productEntityRepository.findUnindexedProducts()).thenReturn(List.of(validProduct, invalidProduct)); - - doThrow(new IllegalArgumentException("Invalid product price")) - .when(productRepository).save(any(Product.class)); - - // Act - try { - inboxProductCreationService.treatInbox(); - } catch (Exception e) { - // Exception expected - } - - // Assert - // Verify that the valid product was not saved because of rollback - verify(productEntityRepository, never()).save(validProduct); - verify(productRepository, times(1)).save(any(Product.class)); // Attempt to save was made - } -}