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

  1. Remove the flags argument when case sensitivity is fine
  2. Pass exactly the literal 'i' when case-insensitive matching is needed
  3. Move flag semantics into the pattern with inline modifiers like '(?i)'
  4. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/bbfb9e70ba14092f. Report an issue: GitHub.