Reputation: 3071
Suppose I'm implementing search functionality for a simple CMS package (just an example), and want to match posts by both their title
and content
. Presumably, I would have some sort of Post
entity with the following underlying table structure:
+------------------------------------+
| POST |
+---------+--------------+-----------+
| post_id | INTEGER | NOT NULL, |
| title | VARCHAR(255) | NOT NULL, |
| content | CLOB | NOT NULL |
+---------+--------------+-----------+
Next, I would extend Spring's JpaRepository
and add the search method via @Query
annotation, like so (again, just an example):
public interface PostRepository extends JpaRepository<Post, Integer> {
@Query("SELECT p FROM Post AS p WHERE lower(p.title) LIKE lower(%:searchTerm%)"
+ " OR lower(p.content) LIKE lower(%:searchTerm%) ORDER BY p.title")
List<Post> findBySearchTerm(@Param("searchTerm") String searchTerm);
}
The problem is that Spring (or maybe it's just the underlying JPA provider, not sure) has a hard time parsing this query due to the lower(%:searchTerm%)
expression in the WHERE
clause. I've also tried other variations of this syntax, e.g. %lower(:searchTerm)%
, but none seem to work so far. Does anybody have a good (and preferably clean) solution for this?
P.S.: I would prefer to use the @Query
annotation for consistency's sake. However, I guess other solutions (such as Spring's method name -> query
derivation or the Criteria API
) are also welcome.
Upvotes: 0
Views: 10979
Reputation: 1626
Try something like this:
@Query("SELECT u.username FROM User u WHERE u.username LIKE
lower(CONCAT('%',:username,'%')"))
List<String> findUsersWithPartOfName(@Param("username") String username);
Notice: The table name in JPQL must start with a capital letter.
Upvotes: 3
Reputation: 7517
1) Inject searchTerm
already in lower case to the method, and use JPQL ..... lower(COLUMN_NAME) like %:searchTerm%
2) Use method names with following naming syntax, so you don't need to provide %
to the JPQL ..... lower(COLUMN_NAME) :searchTerm
findBySearchTermContainingIgnoreCase(String searchTerm)
findBySearchTermStartingWithIgnoreCase(String searchTerm)
Upvotes: 4