K.tas
K.tas

Reputation: 224

How can I search a keyword in entity's list?

My entity has a property of type List<String>. I want to search with the keyword parameter that came to me. If the parameter keyword is in the keywords list of the entity, I want to return this entity. How can I do that?

My entity class:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "product") 
public class Product implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name="title")
    private String title;

    @Column(name="price")
    private Float price;

    @Convert(converter = StringListConverter.class)
    private List<String> image;

    @ElementCollection(targetClass = String.class)
    @Column(name="keywords")
    private List<String> keywords; 
}

I tried this:

public interface ProductRepository extends JpaRepository<Product, Long> {
    Optional<Product> findProductByKeywordsIsLike(String keyword);
}

And also these;

Optional<Product> findProductByKeywords(String keyword);

Optional<Product> findProductByKeywordsContains(String keyword);

Optional<Product> findProductByKeywordsContaining(String keyword);

Optional<Product> findProductByKeywordsIsContaining(String keyword);

Optional<Product> findByKeywords(String keyword);

But unfortunately none of these works. How can I solve this? All of these functions return an empty Optional.

When I use findByKeywordsContaining(String) a crash occurs. The error logs are below:

2021-05-27T04:20:19.190757+00:00 app[web.1]: 2021-05-27 04:20:19.190  WARN 4 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productController' defined in URL [jar:file:/app/target/shopping-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/controller/ProductController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productServiceImpl' defined in URL [jar:file:/app/target/shopping-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/service/impl/ProductServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productRepository' defined in com.repository.ProductRepository 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 java.util.Optional com.repository.ProductRepository.findByKeywordsContaining(java.lang.String)! unknown collection expression type [org.hibernate.query.criteria.internal.path.SingularAttributePath]
2021-05-27T04:20:19.191240+00:00 app[web.1]: 2021-05-27 04:20:19.191  INFO 4 --- [           main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2021-05-27T04:20:19.192738+00:00 app[web.1]: 2021-05-27 04:20:19.192  INFO 4 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2021-05-27T04:20:19.211564+00:00 app[web.1]: 2021-05-27 04:20:19.211  INFO 4 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2021-05-27T04:20:19.212886+00:00 app[web.1]: 2021-05-27 04:20:19.212  INFO 4 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2021-05-27T04:20:19.225628+00:00 app[web.1]: 2021-05-27 04:20:19.225  INFO 4 --- [           main] ConditionEvaluationReportLoggingListener :
2021-05-27T04:20:19.225630+00:00 app[web.1]:
2021-05-27T04:20:19.225631+00:00 app[web.1]: Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-05-27T04:20:19.247757+00:00 app[web.1]: 2021-05-27 04:20:19.247 ERROR 4 --- [           main] o.s.boot.SpringApplication               : Application run failed
2021-05-27T04:20:19.247758+00:00 app[web.1]:
2021-05-27T04:20:19.247760+00:00 app[web.1]: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productController' defined in URL [jar:file:/app/target/shopping-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/controller/ProductController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productServiceImpl' defined in URL [jar:file:/app/target/shopping-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/service/impl/ProductServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productRepository' defined in com.repository.ProductRepository 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 java.util.Optional com.repository.ProductRepository.findByKeywordsContaining(java.lang.String)! unknown collection expression type [org.hibernate.query.criteria.internal.path.SingularAttributePath]
2021-05-27T04:20:19.247761+00:00 app[web.1]: at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247761+00:00 app[web.1]: at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247762+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247762+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247763+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247763+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247764+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247764+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247765+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247765+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247765+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247766+00:00 app[web.1]: at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247766+00:00 app[web.1]: at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247766+00:00 app[web.1]: at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.4.jar!/:2.4.4]
2021-05-27T04:20:19.247767+00:00 app[web.1]: at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:769) [spring-boot-2.4.4.jar!/:2.4.4]
2021-05-27T04:20:19.247767+00:00 app[web.1]: at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) [spring-boot-2.4.4.jar!/:2.4.4]
2021-05-27T04:20:19.247785+00:00 app[web.1]: at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) [spring-boot-2.4.4.jar!/:2.4.4]
2021-05-27T04:20:19.247785+00:00 app[web.1]: at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) [spring-boot-2.4.4.jar!/:2.4.4]
2021-05-27T04:20:19.247786+00:00 app[web.1]: at org.springframework.boot.SpringApplication.run(SpringApplication.java:1313) [spring-boot-2.4.4.jar!/:2.4.4]
2021-05-27T04:20:19.247786+00:00 app[web.1]: at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) [spring-boot-2.4.4.jar!/:2.4.4]
2021-05-27T04:20:19.247786+00:00 app[web.1]: at com.Application.main(ShoppingApplication.java:12) [classes!/:0.0.1-SNAPSHOT]
2021-05-27T04:20:19.247787+00:00 app[web.1]: at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.]
2021-05-27T04:20:19.247787+00:00 app[web.1]: at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.]
2021-05-27T04:20:19.247787+00:00 app[web.1]: at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.]
2021-05-27T04:20:19.247788+00:00 app[web.1]: at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.]
2021-05-27T04:20:19.247789+00:00 app[web.1]: at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) [shopping-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
2021-05-27T04:20:19.247789+00:00 app[web.1]: at org.springframework.boot.loader.Launcher.launch(Launcher.java:107) [shopping-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
2021-05-27T04:20:19.247789+00:00 app[web.1]: at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) [shopping-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
2021-05-27T04:20:19.247789+00:00 app[web.1]: at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) [shopping-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
2021-05-27T04:20:19.247790+00:00 app[web.1]: Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productServiceImpl' defined in URL [jar:file:/app/target/shopping-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/service/impl/ProductServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productRepository' defined in com.repository.ProductRepository 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 java.util.Optional com.repository.ProductRepository.findByKeywordsContaining(java.lang.String)! unknown collection expression type [org.hibernate.query.criteria.internal.path.SingularAttributePath]
2021-05-27T04:20:19.247791+00:00 app[web.1]: at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247791+00:00 app[web.1]: at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247791+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247791+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247792+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247792+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247792+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247793+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247793+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247793+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247796+00:00 app[web.1]: at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247797+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247797+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247798+00:00 app[web.1]: at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247798+00:00 app[web.1]: at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247798+00:00 app[web.1]: ... 28 common frames omitted
2021-05-27T04:20:19.247800+00:00 app[web.1]: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productRepository' defined in com.repository.ProductRepository 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 java.util.Optional com.repository.ProductRepository.findByKeywordsContaining(java.lang.String)! unknown collection expression type [org.hibernate.query.criteria.internal.path.SingularAttributePath]
2021-05-27T04:20:19.247800+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247800+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247801+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247801+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247801+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247801+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247802+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247802+00:00 app[web.1]: at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247802+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247802+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247803+00:00 app[web.1]: at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247803+00:00 app[web.1]: at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247803+00:00 app[web.1]: ... 42 common frames omitted
2021-05-27T04:20:19.247804+00:00 app[web.1]: Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.Optional com.repository.ProductRepository.findByKeywordsContaining(java.lang.String)! unknown collection expression type [org.hibernate.query.criteria.internal.path.SingularAttributePath]
2021-05-27T04:20:19.247805+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:96) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247805+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:107) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247808+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:218) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247808+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:81) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247808+00:00 app[web.1]: at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:100) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247809+00:00 app[web.1]: at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(QueryExecutorMethodInterceptor.java:93) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247809+00:00 app[web.1]: at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.]
2021-05-27T04:20:19.247809+00:00 app[web.1]: at java.util.Iterator.forEachRemaining(Iterator.java:116) ~[na:1.8.]
2021-05-27T04:20:19.247810+00:00 app[web.1]: at java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Collections.java:1051) ~[na:1.8.]
2021-05-27T04:20:19.247810+00:00 app[web.1]: at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) ~[na:1.8.]
2021-05-27T04:20:19.247811+00:00 app[web.1]: at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[na:1.8.]
2021-05-27T04:20:19.247811+00:00 app[web.1]: at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[na:1.8.]
2021-05-27T04:20:19.247811+00:00 app[web.1]: at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.]
2021-05-27T04:20:19.247812+00:00 app[web.1]: at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.]
2021-05-27T04:20:19.247812+00:00 app[web.1]: at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566) ~[na:1.8.]
2021-05-27T04:20:19.247813+00:00 app[web.1]: at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.mapMethodsToQuery(QueryExecutorMethodInterceptor.java:95) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247813+00:00 app[web.1]: at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$new$0(QueryExecutorMethodInterceptor.java:85) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247814+00:00 app[web.1]: at java.util.Optional.map(Optional.java:215) ~[na:1.8.]
2021-05-27T04:20:19.247814+00:00 app[web.1]: at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.<init>(QueryExecutorMethodInterceptor.java:85) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247814+00:00 app[web.1]: at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:303) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247815+00:00 app[web.1]: at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:323) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247815+00:00 app[web.1]: at org.springframework.data.util.Lazy.getNullable(Lazy.java:230) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247815+00:00 app[web.1]: at org.springframework.data.util.Lazy.get(Lazy.java:114) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247816+00:00 app[web.1]: at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:329) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247816+00:00 app[web.1]: at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:144) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247816+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247817+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-5.3.5.jar!/:5.3.5]
2021-05-27T04:20:19.247817+00:00 app[web.1]: ... 53 common frames omitted
2021-05-27T04:20:19.247817+00:00 app[web.1]: Caused by: java.lang.IllegalArgumentException: unknown collection expression type [org.hibernate.query.criteria.internal.path.SingularAttributePath]
2021-05-27T04:20:19.247817+00:00 app[web.1]: at org.hibernate.query.criteria.internal.CriteriaBuilderImpl.isMember(CriteriaBuilderImpl.java:1343) ~[hibernate-core-5.3.10.Final.jar!/:5.3.10.Final]
2021-05-27T04:20:19.247817+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.isMember(JpaQueryCreator.java:331) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247820+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:290) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247820+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:211) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247820+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:124) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247821+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:59) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247821+00:00 app[web.1]: at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:119) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247821+00:00 app[web.1]: at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:95) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247821+00:00 app[web.1]: at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:81) ~[spring-data-commons-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247822+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.<init>(PartTreeJpaQuery.java:217) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247822+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$CountQueryPreparer.<init>(PartTreeJpaQuery.java:348) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247822+00:00 app[web.1]: at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:91) ~[spring-data-jpa-2.4.6.jar!/:2.4.6]
2021-05-27T04:20:19.247822+00:00 app[web.1]: ... 79 common frames omitted
2021-05-27T04:20:19.247823+00:00 app[web.1]:
2021-05-27T04:20:19.682591+00:00 [web.1]: Process exited with status 1
2021-05-27T04:20:19.768332+00:00 [web.1]: State changed from starting to crashed

Edit

ProductController.java:

@RestController
@RequestMapping("/products")
public class ProductController {

    private final ProductService productService;

    public ProductController(ProductService productService){
        this.productService = productService;
    }

    @GetMapping("/voice")
    public
    ResponseEntity<?>
    getProductWithVoice(@RequestParam String keyword){
        Product p = productService.getProductWithVoiceKeyword(keyword);
        if (p != null && !p.isEmpty()) {
            return new ResponseEntity<>(new Response<>(true, 1, p), HttpStatus.OK);
        } else {
            return new ResponseEntity<>(new Response<>(false, 0, null), HttpStatus.NOT_FOUND);
        }
    }
}

Database Table Structure

Upvotes: 1

Views: 2776

Answers (1)

Ilya Sazonov
Ilya Sazonov

Reputation: 1084

So, you want to find a single Product, containing keyword? But findByKeywordsContaining can potentially find several Products. So return type should be List<Product> .

If you want to return Optional<Product>, then your method should be called something like findFirstByKeywordsContaining

Here's a query, Hibernate makes

select
       product0_.id as id1_1_,
       product0_.price as price2_1_,
       product0_.title as title3_1_
from
     products product0_
where
      ? in (
          select
                 keywords1_.keywords
          from
               product_keywords keywords1_
          where
                product0_.id=keywords1_.product_id
          )
;

The query is ok and if you substitute ? for a keyword, it gives right results. But Spring substitutes it for %keyword% (surrounded with percent sign) and it doesn't work of course.

There's another way to what you want.

public interface ProductRepository extends JpaRepository<Product, Long> {
    List<Product> findByKeywordsIn(List<String> keywords);
}

This forms an sql query, which actually gets results, even though you have to provide list of keywords, instead of a single keyword

Hibernate generates another query for that

select
       product0_.id as id1_1_,
       product0_.price as price2_1_,
       product0_.title as title3_1_
from
     products product0_
         left outer join product_keywords keywords1_
             on product0_.id=keywords1_.product_id

where 
     keywords1_.keywords in (?)

And Spring passeds an array to ? parameter, so everything works.

As far as I understand, both queries are roughly equivalent, because RDBMS engine should optimize them to the same execution plan. But it depends on RMBMS implementation and indices.

Upvotes: 1

Related Questions