How can we do a ignorecase in the criteria builder? If I have
private final CriteriaBuilder cb
then I can only use cb.asc
or cb.desc
, but not ignoring case.
How can we do a ignorecase in the criteria builder
1. Force Ignorecase in JPA Program - Does the Job, Answers the Q Directly
JPA ORDER BY Two Columns, Ignoring Case:
Order lcSurnameOrder = criteriaBuilder.order(
criteriaBuilder.lower(Person_.surname));
Order lcFirstnameOrder = criteriaBuilder.order(
criteriaBuilder.lower(Person_.firstname));
criteriaQuery.orderBy(lcSurnameOrder, lcFirstnameOrder);
JPA LIKE, Ignoring Case:
Predicate lcSurnameLikeSearchPattern = criteriaBuilder.like(
criteriaBuilder.lower(Person_.surname),
searchPattern.toLowerCase());
criteriaQuery.where(lcSurnameLikeSearchPattern);
Assumes Person_ canonical metamodel class was generated from Person entity, to give strong-typed use of JPA criteria API.
TIP: For best performance & control, consider converting string columns to LOWER case or INITCAP case just once - when you INSERT/UPDATE into the database. Do the same conversion for user-entered search patterns.
2. ALTERNATIVE: Apply Collation in the Database - Best Practice, Simpler, More Performant
The SQL-99 standard has a built-in modifer to compare characters in Strings according to rules:
COLLATE <collation name>
Can use when comparing, sorting and grouping on strings. A common example that ignores case:
COLLATE SQL_Latin1_General_CP1_CI_AS
Or
COLLATE latin1_general_cs
You can even create your own custom collation:
CREATE COLLATION <collation name> FOR <character set specification>
FROM <existing collation name> [ <pad characteristic> ]
Collation is applied in the DB via one of the following alternatives (from localised to global effect):
WHERE Clause (=, LIKE, HAVING, >, >=, etc)
WHERE <expression> = <expression> [COLLATE <collation name>]
WHERE <expression> LIKE <expression> [COLLATE <collation name>]
SELECT DISTINCT Clause
SELECT DISTINCT <expression> [COLLATE <collation name>], ...
ORDER BY Clause
ORDER BY <expression> [COLLATE <collation name>]
GROUP BY Clause
GROUP BY <expression> [COLLATE <collation name>]
Column Definition
CREATE TABLE <table name> (
<column name> <type name> [DEFAULT...]
[NOT NULL|UNIQUE|PRIMARY KEY|REFERENCES...]
[COLLATE <collation name>],
...
)
Domain Definition
CREATE DOMAIN <domain name> [ AS ] <data type>
[ DEFAULT ... ] [ CHECK ... ] [ COLLATE <collation name> ]
Character Set Definition
CREATE CHARACTER SET <character set name>
[ AS ] GET <character set name> [ COLLATE <collation name> ]
The first 4 cases can't be used with JPA, because these SQL commands are generated by JPA, and JPA standard does not support collation.
3. ALTERNATIVE (PROPRIETARY) Oracle also provides NLS settings to ignore case across entire DB instance (can be set in config files):
ALTER SESSION SET NLS_COMP='BINARY'; -- Case Sensitive
ALTER SESSION SET NLS_COMP='ANSI'; -- Ignore for LIKE but not =,<,etc
ALTER SESSION SET NLS_COMP='LINGUISTIC';-- Ignore for LIKE,=,<,etc (post 10gR2)
ALTER SESSION SET NLS_SORT='BINARY' ; -- Case Sensitive
ALTER SESSION SET NLS_SORT='BINARY_CI'; -- Ignore
ALTER SESSION SET NLS_SORT='XSPANISH'; -- Ignore according to language rules
ALTER SESSION SET NLS_SORT='LATIN1_GENERAL_CS';
Plus functions to ignore case as one-off
ORDER BY NLSSORT(supplier_name,'NLS_SORT=BINARY_CI') ;
You can call this via
criteriaBuilder.function("nlssort", String.class, dept_.suppler_name, "NLS_SORT=BINARY_CI");
and then call criteriaQuery.orderyBy
or select
, etc