126

With Spring CrudRepository Query; I want to select "DeviceType" entities with it's "name" property. But following query select the entitles on case sensitive manner. How I make it case insensitive way. Thanks.

public interface DeviceTypeRepository extends CrudRepository<DeviceType, Integer>, JpaSpecificationExecutor<DeviceType> {

    public Iterable<DeviceType> findByNameContaining(String name);

}  
Channa
  • 4,963
  • 14
  • 65
  • 97
  • 23
    Did you try `public Iterable findByNameIgnoreCaseContaining(String name);`? – Peter Keller Mar 22 '14 at 12:21
  • In case if you interested in Query then please try this, No need to give '%' after LIKE @Query(value= "select dt from DeviceType as dt where lower(dt.name) like lower(:name)") public Iterable anyMethodNameGoesHere(@Param(name) String name); – Java_Fire_Within Dec 01 '17 at 20:00
  • This may help you, https://stackoverflow.com/questions/37178520/jpql-like-case-insensitive/62988377#62988377 – Shashank Jul 20 '20 at 03:50

6 Answers6

247

Exactly as @Peter mentioned in the comment, just add IgnoreCase:

public interface DeviceTypeRepository 
    extends CrudRepository<DeviceType, Integer>, JpaSpecificationExecutor<DeviceType> {

    public Iterable<DeviceType> findByNameContainingIgnoreCase(String name);
}  

See documentation for a list of all supported keywords inside method names.

Roadrunner
  • 6,661
  • 1
  • 29
  • 38
  • Thanks a lot for the answer; sure I will refer that documentation. May Thanks. Have a great time ! – Channa Mar 22 '14 at 16:25
  • 3
    It worked for me. I was using JPA query. So as per the documentation, where UPPER(x.firstame) = UPPER(?1) worked. – sunitha Jul 02 '18 at 10:07
  • @sunitha do you know of any way we could modify this behaviour, say make it LOWER? My db has indexing based on lower case – Sudip Bhandari Aug 30 '18 at 06:47
  • @SudipBhandari : Sure u can. – sunitha Aug 30 '18 at 10:01
  • Doesn't work for me. More here: https://stackoverflow.com/questions/56171569/spring-with-crudrepository-and-ignorecase – JackTheKnife May 17 '19 at 13:13
  • 3
    For multiple properties repead `IgnoreCase` like this: `List findByUsernameIgnoreCaseAndDomainIgnoreCase(String username, String domain);` – Tarator May 24 '19 at 10:21
  • remember to extend the interface _JpaSpecificationExecutor_ in your repository – Maurizio Lo Bosco Jun 13 '19 at 14:10
  • does this apply to all parameters or only for the one after which it is specified. For example if I wanted to find by first name and last name both case insensitive, would i do findByFirstNameIgnoreCaseAndLastNameIgnoreCase or findByFirstNameAndLastNameIgnoreCase ? – Don Code Dec 05 '19 at 00:05
  • Roadrunner, @sunitha Can i use this method name with pageable as second param, will it work ? – Derrick May 26 '20 at 18:39
  • `findByNameContainingIgnoreCaseOrderByNameAsc` in finde by name containing + ignore case + order by column name ascending – tarcnux Mar 07 '21 at 01:29
13

The following Spring data mongo query works for me. I would prefer to use List instead of Iterator

public interface DeviceTypeRepository extends CrudRepository<DeviceType,Integer>, JpaSpecificationExecutor<DeviceType> {
    List<DeviceType> findByNameIgnoreCase(String name);
} 
2

In my case adding IgnoreCase did not work at all.

I found that it is possible to provide options for the regular expression ,as well:

@Query(value = "{'title': {$regex : ?0, $options: 'i'}}")
Foo findByTitleRegex(String regexString);

The i option makes the query case-insensitive.

rocksteady
  • 2,320
  • 5
  • 24
  • 40
2

For those who uses custom JPA query Upper keyword and toUpperCase helps. The following code works for me

 return  entityManager.createQuery("select q from "table " q  where upper(q.applicant)=:applicant")
    .setParameter("applicant",applicant.toUpperCase().trim()).getSingleResult();
Dapper Dan
  • 932
  • 11
  • 23
  • 1
    Be carefull when use 'upper(q.applicant)'. In Postgres it causes '.PSQLException: ERROR: function upper(bytea) does not exist' when q.applicant is null – advortsov Oct 17 '19 at 09:05
0

In my case adding IgnoreCase work like this. i would prefer to use list instead of iterator

public List<ContactEntity> findByNameIgnoreCaseContainingAndUserEntity(String name, UserEntity userEntity);
0

While, I think, answers already provided bring some bits of useful information, I also think that they are lacking.

Spring Data JPA's query building/generation mechanism parses the names of methods that are explicitly (by developer) declared in the custom repository interfaces (which extend CrudRepository<T, ID> or any of its subtypes) and based on those names, it generates native queries for the corresponding backing datastore/database.

Let's say, we have an managed type (i.e. @Entity) Person, as follows:

class Person {
    @Id
    private Integer id;
    private String firstname;
    private String lastname;
    private Integer age;
    
    //getters, setters, constructor, etc.
}

and a corresponding repository, that works with this entity:

interface PersonRepository<Person, Integer> {
}

In order to instruct Spring Data JPA to ignore the case of values provided as arguments to the user-declared repository methods, you can use:

  1. IgnoreCase - for ignoring case-sensitivity of the specific field; or
  2. AllIgnoreCase - for ignoring case-sensitivity of all the fields.

Note, that while you should be placing IgnoreCase right after the field you want to ignore case-sensitivity for, you can place AllIgnoreCase in almost any place of a method name that you declare.

Ignore case-sensitivity for the specific fields/columns:

Ignores the case of firstname and lastname values:

List<Person> findByFirstnameIgnoreCaseAndLastnameIgnoreCase(String firstname, String lastname);

Ignores the case of lastname value:

List<Person> findByFirstnameAndLastnameIgnoreCase(String firstname, String lastname);

Ignores the case of firstname value:

List<Person> findByFirstnameIgnoreCaseAndLastname(String firstname, String lastname);

Ignore case-sensitivity for all the fields/columns:

Placing AllIgnoreCase right before any parameter name:

List<Person> findByAllIgnoreCaseFirstnameAndLastname(String firstname, String lastname);

or after only some parameter name:

List<Person> findByFirstnameAllIgnoreCaseAndLastname(String firstname, String lastname);

or in the end, after all the parameter names:

List<Person> findByFirstnameAndLastnameAllIgnoreCase(String firstname, String lastname);

or even in the very beginning, swapping findBy with it:

List<Person> AllIgnoreCaseFirstnameAndLastname(String firstname, String lastname);

would all result in the same behaviour - ignoring case-sensitivity for all the fields/columns when generating query.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66