147

I would like to write a like query in JpaRepository but it is not returning anything :

LIKE '%place%'-its not working.

LIKE 'place' works perfectly.

Here is my code :

@Repository("registerUserRepository")
public interface RegisterUserRepository extendsJpaRepository<Registration,Long> {

    @Query("Select c from Registration c where c.place like :place")
     List<Registration> findByPlaceContaining(@Param("place")String place);
}
catch23
  • 17,519
  • 42
  • 144
  • 217
sudeep cv
  • 1,901
  • 4
  • 16
  • 19

16 Answers16

260

The spring data JPA query needs the "%" chars as well as a space char following like in your query, as in

@Query("Select c from Registration c where c.place like %:place%").

Cf. http://docs.spring.io/spring-data/jpa/docs/current/reference/html.

You may want to get rid of the @Queryannotation alltogether, as it seems to resemble the standard query (automatically implemented by the spring data proxies); i.e. using the single line

List<Registration> findByPlaceContaining(String place);

is sufficient.

Hille
  • 4,096
  • 2
  • 22
  • 32
  • 37
    It may be useful also to ignore case for a query, using: findByPlaceIgnoreCaseContaining(String place); – ilyailya Jan 15 '16 at 15:39
  • 1
    Just as a side comment - you can't mix and match %:param% with %param% inside the same query. Otherwise the app will not even start. – RVP Apr 18 '16 at 09:43
  • 2
    Thank you. I used to write `like '%:place%'` with `'` and there were no results at all, because Hibernate adds `'`s to strings by itself. – Yamashiro Rion Jan 14 '19 at 06:12
  • This is not a good response and it is potentially dangerous as well. Spring has this sorted out with ContainingIgnoreCase, check my answer bellow. – Alexius DIAKOGIANNIS Apr 17 '20 at 07:53
  • 1
    @Query("Select c from Registration c where c.place like %:place%"). is not working in Spring Boot Version 2.3.3. would you please give some idea about why can I make it work while using 2.3.3 –  Dec 02 '20 at 09:54
  • 1
    @SubhaBhowmik Which version is exactly not working? You say for 2.3.3 it's working and not working. I was also struggling with %:param% with Spring Boot 2.4.0 but figured out that you cannot have %:param% inside an SQL function: F.e. in LOWER('%:param%') the :param is not substituted because of the quote signs. Hope that can help you. – Sebastian S. Dec 02 '20 at 12:52
  • like with ignore case `@Query("Select c from Registration c where lower(c.place) like lower(concat('%', :place,'%')")` – Tharindu Krishan Mar 08 '23 at 18:47
  • This doesn't work with reactive driver (R2DBC). Got ```io.r2dbc.postgresql.ExceptionFactory$PostgresqlBadGrammarException: [42601] syntax error at or near "%"``` – yauritux Aug 13 '23 at 15:34
128

You dont actually need the @Query annotation at all.

You can just use the following

    @Repository("registerUserRepository")
    public interface RegisterUserRepository extends JpaRepository<Registration,Long>{
    
    List<Registration> findByPlaceIgnoreCaseContaining(String place);

    }
Alexius DIAKOGIANNIS
  • 2,465
  • 2
  • 21
  • 32
  • 1
    For me this one is the best solution. i didn't know you can use IgnoreCase combined with Containing, It isn't in the documentation. – Wilson Campusano Jan 18 '17 at 15:23
  • 4
    What about the case when I want to use many columns ? - I believe `@Query()` is a must, right ? With that approach I would have to make `or` that isn't actually a well suited solution for that case:`findByField1OrField2Containg(String phraseForField1, String phraseForField2)` – user3529850 Mar 21 '18 at 09:32
42

For your case, you can directly use JPA methods. That code is like bellow :

Containing: select ... like %:place%

List<Registration> findByPlaceContainingIgnoreCase(String place);

here, IgnoreCase will help you to search item with ignoring the case.

Using @Query in JPQL :

@Query("Select registration from Registration registration where 
registration.place LIKE  %?1%")
List<Registration> findByPlaceContainingIgnoreCase(String place);

Here are some related methods:

  1. Like findByPlaceLike

    … where x.place like ?1

  2. StartingWith findByPlaceStartingWith

    … where x.place like ?1 (parameter bound with appended %)

  3. EndingWith findByPlaceEndingWith

    … where x.place like ?1 (parameter bound with prepended %)

  4. Containing findByPlaceContaining

    … where x.place like ?1 (parameter bound wrapped in %)

More info, view this link (where the above quote is from), this link and this

blackgreen
  • 34,072
  • 23
  • 111
  • 129
Md. Sajedul Karim
  • 6,749
  • 3
  • 61
  • 87
32

You can also implement the like queries using Spring Data JPA supported keyword "Containing".

List<Registration> findByPlaceContaining(String place);
amanzoor
  • 389
  • 4
  • 6
10

Try this.

@Query("Select c from Registration c where c.place like '%'||:place||'%'")
Ashu
  • 101
  • 1
  • 2
7

You can have one alternative of using placeholders as:

@Query("Select c from Registration c where c.place LIKE  %?1%")
List<Registration> findPlaceContainingKeywordAnywhere(String place);
Nitin Pawar
  • 1,634
  • 19
  • 14
6

I use this:

@Query("Select c from Registration c where lower(c.place) like lower(concat('%', concat(:place, '%')))")

lower() is like toLowerCase in String, so the result isn't case sensitive.

Mateusz Niedbal
  • 326
  • 4
  • 15
  • I use the same method but when variable in lower function is null I get the following error, how to add a null check? function lower(bytea) does not exist – arslanbenzer Dec 04 '20 at 06:48
3

when call funtion, I use: findByPlaceContaining("%" + place);

or: findByPlaceContaining(place + "%");

or: findByPlaceContaining("%" + place + "%");

Ayo K
  • 1,719
  • 2
  • 22
  • 34
2

We can use native query

@Query(nativeQuery = true, value ="Select * from Registration as c where c.place like %:place%")

List<Registration> findByPlaceContaining(@Param("place")String place);
Aasim ali
  • 318
  • 4
  • 6
2

I had to use something like this CONCAT('%',:setName,'%')

Procrastinator
  • 2,526
  • 30
  • 27
  • 36
1

answer exactly will be

-->` @Query("select u from Category u where u.categoryName like %:input%")
     List findAllByInput(@Param("input") String input);
1

There can be various approaches. As mentioned in answer of many, if possible you can use JPA predefined template query.

List<Registration> findByPlaceContainingIgnoreCase(String place);

Also, you can append '%' in java layer before calling the above method.

If complex query, then you can normally use @Query one

@Query("Select r from Registration r where r.place like '%' || :place || '%'")

For readability, you can use below one

@Query("Select r from Registration r where r.place like CONCAT('%', :place, '%'")
Satish Patro
  • 3,645
  • 2
  • 27
  • 53
0

Found solution without @Query (actually I tried which one which is "accepted". However, it didn't work).

Have to return Page<Entity> instead of List<Entity>:

public interface EmployeeRepository 
                          extends PagingAndSortingRepository<Employee, Integer> {
    Page<Employee> findAllByNameIgnoreCaseStartsWith(String name, Pageable pageable);
}

IgnoreCase part was critical for achieving this!

catch23
  • 17,519
  • 42
  • 144
  • 217
0

You can just simply say 'Like' keyword after parameters..

List<Employee> findAllByNameLike(String name);
0

Us like this

@Query("from CasFhgDeviceView where deviceGroupName like concat(concat('%CSGW%', :usid), '%') ")

  • Does this answer provide more information than the other answers? If so, please [edit] it and add information about what your answer helps solve. If not, please delete your answer. Thanks. – Mark Stewart Nov 10 '21 at 21:45
0

This is now possible with Spring Data JPA. Check out http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#query-by-example

Registration registration = new Registration();
registration.setPlace("UK");

ExampleMatcher matcher = ExampleMatcher.matchingAll()
  .withIgnoreCase()
  .withStringMatcher(StringMatcher.CONTAINING);

Example<Registration> example = Example.of(registration, matcher);

List<Registration> registrationList = registerUserRepository.findAll(example);
Mohamed AbdElRazek
  • 1,654
  • 14
  • 17