I’m trying to measure time when loading data using jpa and mysql in spring boot.
Product.java
@Entity
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Table(name = "tbl_product")
@EntityListeners(AuditingEntityListener.class)
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long pno;
private String pname;
private int price;
private String pdesc;
private boolean delFlag;
private Long categoryNum;
@CreatedDate
private LocalDateTime date;
@Builder.Default
private Long viewCount= Long.valueOf(0);
@ManyToOne(fetch = FetchType.EAGER)
private User seller;
@ElementCollection(fetch = FetchType.EAGER)
@Builder.Default
private List<ProductImage> imageList = new ArrayList<>();
public void changePrice(int price) {
this.price = price;
}
public void changeDesc(String desc) {
this.pdesc = desc;
}
public void changeName(String name) {
this.pname = name;
}
public void addImage(ProductImage image) {
image.setOrd(this.imageList.size());
imageList.add(image);
}
public void addImageString(String fileName) {
ProductImage productImage = ProductImage.builder()
.fileName(fileName)
.build();
addImage(productImage);
}
public void clearList() {
this.imageList.clear();
}
public void setSeller(User seller) {
this.seller = seller;
}
}
ProductImage.java
@Embeddable
@Getter
@ToString
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ProductImage {
private String fileName;
private int ord;
public void setOrd(int ord){
this.ord = ord;
}
}
ProductController.java
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/products")
@Log4j2
@Tag(name = "Product", description = "Product API")
public class ProductController {
private final ProductService productService;
private final CustomFileUtil fileUtil;
@GetMapping("/search")
public ResponseEntity<?> searchProducts(@RequestParam String query) {
try {
List<ProductDTO> products = productService.searchProducts(query);
log.info(products);
return ResponseEntity.ok(products);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
}
}
ProductService.java
public interface ProductService {
List<ProductDTO> searchProducts(String query);
}
ProductServiceImpl.java
@Service
@RequiredArgsConstructor
@Slf4j
public class ProductServiceImpl implements ProductService {
private final ProductRepository productRepository;
private final UserRepository userRepository;
@Override
public List<ProductDTO> searchProducts(String query) {
List<Product> products = productRepository.findByPnameContainingIgnoreCase(query);
List<ProductDTO> dtoList = products.stream().map(el -> entityToDTO(el)).collect(Collectors.toList());
return dtoList;
}
private ProductDTO entityToDTO(Product product) {
ProductDTO productDTO = ProductDTO.builder()
.pno(product.getPno())
.pname(product.getPname())
.pdesc(product.getPdesc())
.price(product.getPrice())
.seller(product.getSeller().getUserName())
.viewCount(product.getViewCount())
.categoryNum(product.getCategoryNum())
.build();
List<ProductImage> imageList = product.getImageList();
if(imageList == null || imageList.size() == 0 ){
return productDTO;
}
List<String> fileNameList = imageList.stream().map(productImage -> productImage.getFileName()).toList();
productDTO.setUploadFileNames(fileNameList);
return productDTO;
}
}
ProductRepository.java
public interface ProductRepository extends JpaRepository<Product, Long> {
List<Product> findByPnameContainingIgnoreCase(String query);
}
If the product name is “Product 1”, “Product 2”, “Product 3″… “Product 1000” and search for the word “product” as a keyword, all products will be returned in List format in 10 seconds.
However, if I use the findall() function on the Product it takes less than 1 seconds in total.
I would like to know why this API takes 10 seconds.
I also measured the time using mysql workbench and postman, but it took less than 2 seconds in total.
I solved the problem through fetch join, but even after searching, I couldn’t find why it took 10 seconds.