I had a task to get all things in the range from the minimum to the maximum price. From my attempts, I tried changing List to Set to store only unique objects, but it did not help, I also tried to make FetchType.EAGER in two entity classes, but this also did not help
controller
@GetMapping("/get-item")
@PreAuthorize(RoleExpressions.PERMIT_ALL)
public Page<Item> getItems(BigDecimal minPrice, BigDecimal maxPrice){
return itemRepository.findAllByPrices(
priceRepository.findAllByPriceBetween(minPrice, maxPrice),
PageRequest.of(0, 10, Sort.Direction.DESC));
}
item repository
public interface ItemRepository extends JpaRepository<Item, Long>, JpaSpecificationExecutor<Item> {
Page<Item> findAllByPrices(List<Price> prices, Pageable pageable);
}
price repository
public interface PriceRepository extends JpaRepository<Price, Long>{
List<Price> findAllByPriceBetween(BigDecimal minPrice, BigDecimal maxPrice);
}
item entity
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "item")
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "item_id")
@SequenceGenerator(name = "item_id", sequenceName = "item_id_seq")
private Long id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "thumbnail", nullable = false)
private String thumbnail;
@Column(name = "photo", nullable = false)
private String photo;
@Column(name = "short_description", nullable = false)
private String shortDescription;
@Column(name = "description", nullable = false)
private String description;
@ManyToOne
@JoinColumn(nullable = false)
private Category category;
@OneToMany(mappedBy = "item", cascade = CascadeType.REMOVE)
@Builder.Default
private List<Price> prices = new ArrayList<>();
}
price entity
@Entity
@Table(name = "price_information")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Price {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "news_id")
@SequenceGenerator(name = "news_id", sequenceName = "news_id_seq")
private Long id;
@Column(name = "price", nullable = false)
private BigDecimal price;
@Column(name = "date", nullable = false)
private LocalDateTime date;
@ManyToOne
@JoinColumn(nullable = false)
@EqualsAndHashCode.Exclude
private Item item;
}
exception
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'itemController' defined in file [D:\issue_operation_img_testing\angulartrainee-backend\build\classes\java\main\com\elinext\angulartrainee\controller\ItemController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'itemServiceImpl' defined in file [D:\issue_operation_img_testing\angulartrainee-backend\build\classes\java\main\com\elinext\angulartrainee\service\impl\ItemServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'itemRepository' defined in com.elinext.angulartrainee.repository.ItemRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract org.springframework.data.domain.Page com.elinext.angulartrainee.repository.ItemRepository.findAllByPrices(java.util.List,org.springframework.data.domain.Pageable)! Operator SIMPLE_PROPERTY on prices requires a scalar argument, found interface java.util.List in method public abstract org.springframework.data.domain.Page com.elinext.angulartrainee.repository.ItemRepository.findAllByPrices(java.util.List,org.springframework.data.domain.Pageable).
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:799)
Caused by: java.lang.IllegalStateException: Operator SIMPLE_PROPERTY on prices requires a scalar argument, found interface java.util.List in method public abstract org.springframework.data.domain.Page com.elinext.angulartrainee.repository.ItemRepository.findAllByPrices(java.util.List,org.springframework.data.domain.Pageable).
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.throwExceptionOnArgumentMismatch(PartTreeJpaQuery.java:171)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.validate(PartTreeJpaQuery.java:147)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:90)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.<init>(QueryExecutorMethodInterceptor.java:84)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:332)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$4(RepositoryFactoryBeanSupport.java:294)
at org.springframework.data.util.Lazy.getNullable(Lazy.java:211)
at org.springframework.data.util.Lazy.get(Lazy.java:95)
CodePudding user response:
Your repository method should be changed to:
Page<Item> findAllByPricesIn(List<Price> prices, Pageable pageable);
If the objective is to find "all Items" that have a price within the Collection of prices you are passing as parameter.
Using IN
which is part of Spring Data JPA supported keywords in methods
.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation