hibernate/hibernate-orm · error · IllegalArgumentException
MariaDB and legacy MySQL only support the case insensitive f
Error message
MariaDB and legacy MySQL only support the case insensitive flag 'i' as literal.
What it means
On MariaDB and legacy MySQL, Hibernate renders the regexp predicate with lower(...) wrapping for case-insensitivity. The flags argument must be the literal string 'i'; any other value or a non-literal flags expression throws IllegalArgumentException at rendering, because plain REGEXP/RLIKE on those databases exposes no flags.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/RegexpPredicateFunction.java:37
*/
public class RegexpPredicateFunction extends AbstractRegexpLikeFunction {
public RegexpPredicateFunction(TypeConfiguration typeConfiguration) {
super( typeConfiguration );
}
@Override
public void render(
SqlAppender sqlAppender,
List<? extends SqlAstNode> arguments,
ReturnableType<?> returnType,
SqlAstTranslator<?> walker) {
final boolean caseSensitive;
if ( arguments.size() > 2 ) {
if ( !(arguments.get( 2 ) instanceof Literal literal)
|| !(literal.getLiteralValue() instanceof String flags)
|| !flags.equals( "i" ) ) {
throw new IllegalArgumentException( "MariaDB and legacy MySQL only support the case insensitive flag 'i' as literal." );
}
caseSensitive = false;
}
else {
caseSensitive = true;
}
if ( !caseSensitive ) {
sqlAppender.appendSql( "lower(" );
}
arguments.get( 0 ).accept( walker );
if ( !caseSensitive ) {
sqlAppender.appendSql( ')' );
}
sqlAppender.appendSql( " regexp " );
if ( caseSensitive ) {
sqlAppender.appendSql( "binary " );
}View on GitHub (pinned to fad1729dce)
Solutions
- Remove the flags argument when case sensitivity is fine
- Pass exactly the literal 'i' when case-insensitive matching is needed
- Move flag semantics into the pattern with inline modifiers like '(?i)'
- Run the query as native SQL for advanced regex flags
Example fix
// before where regexp_like(e.code, :pattern, 'im') // after where regexp_like(e.code, '(?im)' || :pattern) -- only 'i' is accepted as a flag literal
Defensive patterns
Strategy: validation
Validate before calling
// MariaDB/legacy MySQL: only the literal 'i' is a valid regexp flag
static String sanitizeMysqlFlags(String flags) {
if (flags == null || flags.isEmpty()) return null;
if (!"i".equals(flags)) {
throw new IllegalArgumentException("Only flag 'i' is supported, got: " + flags);
}
return flags;
} Try / catch
try {
return em.createQuery(hql).getResultList();
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("case insensitive flag")) {
return em.createQuery(lowercasedOperands(hql)).getResultList(); // lower() both operands
}
throw e;
} Prevention
- Never parameterize regexp flags on MariaDB/MySQL
- Keep flag handling per-dialect in a small helper instead of inline HQL
- Test regex queries against every backend in the support matrix
When it happens
Trigger: HQL: regexp_like(e.col, 'pat', 'g') or flags bound as a parameter/concatenation on MariaDB or legacy MySQL dialects.
Common situations: Test suites on MariaDB/MySQL rejecting HQL that works on Oracle or PostgreSQL; runtime-built flag strings; upgrading from Hibernate 5 regex handling to 6/7 dialect functions.
Related errors
- HSQLDB only supports the case insensitive flag 'i' as litera
- PostgreSQL and CockroachDB only support the case insensitive
- Unexpected row count (the expected row count for an ON DUPLI
- Insert conflict 'do update' clause with constraint name is n
- The {storageEngine} storage engine is not supported
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/bbfb9e70ba14092f.
Report an issue: GitHub.