i’m trying to do this query
List<Product> findProductByCategory_CategoryNameAndPriceBetween(String category, double min, double max);
but the return of the query is an empty list. What am I doing wrong? I also tried without the underscore between Category and Category Name. This are the class category and product:
JavaScript
x
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="ID")
private Long id;
@Column(name = "NAME")
private String categoryName;
@OneToMany(mappedBy = "category", fetch = FetchType.EAGER)
private List<Product> products;
}
JavaScript
@Entity
@Table(name="PRODUCT")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="ID")
private Long id;
@Column(name="PRICE")
private Double price;
@Column(name="BRAND")
private String brand;
@Column(name="MODEL")
private String model;
//@Lob
@Column(name="DESCRIPTION")
private String description;
@Column(name = "IMAGE_URL")
private String imageUrl;
@ManyToOne
@JoinColumn(name = "CATEGORY_ID", referencedColumnName = "ID")
private Category category;
And this is how I have implemented the repository:
JavaScript
@Repository
public interface ProductDao extends JpaRepository<Product,Long> {
Advertisement
Answer
With the implementation below, your query is doing just fine.
Please note that I’ve added an alternative implementation:
JavaScript
List<Product> findByCategoryAndPriceBetween(Category category, double min, double max);
I suspect that when you are testing this, you are not saving any products because your code is missing cascading inside Category
class. Hence, I’ve added my implementation used during tests.
Category class
JavaScript
package no.mycompany.myapp.misc;
import lombok.Data;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Data
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private Long id;
@Column(name = "NAME")
private String categoryName;
@OneToMany(mappedBy = "category", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Product> products = new ArrayList<>();
}
Product class
JavaScript
package no.mycompany.myapp.misc;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
// cannot use @Data here because of circular ref
@Getter
@Setter
@Entity
@Table(name="PRODUCT")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="ID")
private Long id;
@Column(name="PRICE")
private Double price;
@Column(name="BRAND")
private String brand;
@Column(name="MODEL")
private String model;
//@Lob
@Column(name="DESCRIPTION")
private String description;
@Column(name = "IMAGE_URL")
private String imageUrl;
@ManyToOne
@JoinColumn(name = "CATEGORY_ID", referencedColumnName = "ID")
private Category category;
}
ProductDao
JavaScript
public interface ProductDao extends JpaRepository<Product, Long> {
List<Product> findProductByCategory_CategoryNameAndPriceBetween(String category, double min, double max);
List<Product> findByCategoryAndPriceBetween(Category category, double min, double max);
}
Let’s add a couple of tests about this:
JavaScript
package no.mycompany.myapp.misc;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.ActiveProfiles;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@DataJpaTest
public class ProductDaoTest {
@Autowired
ProductDao productDao;
@Autowired
TestEntityManager testEntityManager;
@Test
public void findByCategoryAndPriceBetween_singleCategoryWithSingleProductInDb_expectSingleProduct() {
var category = createCategoryWithSingleProduct();
testEntityManager.persist(category);
var result = productDao.findByCategoryAndPriceBetween(category, 0.0, 2.0);
assertThat(result.size()).isEqualTo(1);
}
@Test
public void findByCategoryAndPriceBetween_singleCategoryWithSingleProductInDb_expectEmptyResult() {
var category = createCategoryWithSingleProduct();
testEntityManager.persist(category);
var result = productDao.findByCategoryAndPriceBetween(category, 5.0, 6.0);
assertThat(result.size()).isEqualTo(0);
}
@Test
public void findProductByCategory_CategoryNameAndPriceBetween_singleCategoryWithSingleProductInDb_expectSingleProduct() {
var category = createCategoryWithSingleProduct();
testEntityManager.persist(category);
var result = productDao.findProductByCategory_CategoryNameAndPriceBetween(category.getCategoryName(), 0.0, 2.0);
assertThat(result.size()).isEqualTo(1);
}
private static Category createCategoryWithSingleProduct() {
Product product = new Product();
product.setPrice(1.00);
Category category = new Category();
category.setCategoryName("test");
category.getProducts().add(product);
product.setCategory(category);
return category;
}
}