hibernate/hibernate-orm · error · SemanticException
Illegal format pattern '{}'
Error message
Illegal format pattern '{}' What it means
The HQL format() function wraps its datetime pattern in an SqmFormat node whose constructor validates the pattern against a whitelist regex of supported DateTimeFormatter elements: quoted literals, punctuation separators, whitespace, and limited runs of G, y/Y, M, w, W, E, e, d, D, a, H/h/m/s, S, z/Z/x. Any pattern outside this subset throws SemanticException('Illegal format pattern ...') at query interpretation time.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmFormat.java:53
// a AM/PM
// H hour of day (0-23)
// h clock hour of am/pm (1-12)
// m minute of hour
// s second of minute
// S fraction of second
// z time zone name e.g. PST
// x zone offset e.g. +03, +0300, +03:00
// Z zone offset e.g. +0300
// see https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
private static final Pattern FORMAT = Pattern.compile( "('[^']+'|[:;/,.!@#$^&?~`|()\\[\\]{}<>\\-+*=]|\\s|G{1,2}|[yY]{1,4}|M{1,4}|w{1,2}|W|E{3,4}|e{1,2}|d{1,2}|D{1,3}|a|[Hhms]{1,2}|S{1,6}|[zZx]{1,3})*");
public SqmFormat(
String value,
SqmBindableType<String> inherentType,
NodeBuilder nodeBuilder) {
super(value, inherentType, nodeBuilder);
if (!FORMAT.matcher(value).matches()) {
throw new SemanticException("Illegal format pattern '" + value + "'");
}
}
@Override
public @Nonnull SqmBindableType<String> getNodeType() {
return castNonNull( super.getNodeType() );
}
@Override
public @Nonnull String getLiteralValue() {
return castNonNull( super.getLiteralValue() );
}
@Override
public SqmFormat copy(SqmCopyContext context) {
final SqmFormat existing = context.getCopy( this );
if ( existing != null ) {
return existing;View on GitHub (pinned to fad1729dce)
Solutions
- Rewrite the pattern using only supported elements: u -> y, quarter -> month or precomputed quoted text.
- Wrap literal characters (including unsupported letters used as text) in single quotes: 'Q' or 'T'.
- Do complex formatting in Java after fetching, or fall back to a native query with the dialect's own format function when the pattern cannot be expressed.
Example fix
-- before select format( e.ts as 'yyyy QQ u' ) from Event e -- Q and u not supported -- after select format( e.ts as 'yyyy MM dd' ) from Event e
Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern HQL_FORMAT = Pattern.compile(
"('[^']+'|[:;/,.!@#$^&?~`|()\\[\\]{}<>\\-+*=]|\\s|G{1,2}|[yY]{1,4}|M{1,4}|w{1,2}|W|E{3,4}|e{1,2}|d{1,2}|D{1,3}|a|[Hhms]{1,2}|S{1,6}|[zZx]{1,3})*");
static String checkHqlFormat(String pattern) {
if ( !HQL_FORMAT.matcher( pattern ).matches() ) {
throw new IllegalArgumentException( "Pattern not supported by HQL format(): " + pattern );
}
return pattern;
} Try / catch
try {
return em.createQuery( hql ).getResultList();
} catch ( org.hibernate.query.SemanticException e ) {
throw new IllegalArgumentException( "Bad format pattern: " + e.getMessage(), e );
} Prevention
- Restrict format patterns to the documented HQL subset (G, y/Y, M, w, W, E, e, d, D, a, H/h/m/s, S, z/Z/x, quoted text, separators).
- Validate user-supplied patterns against the same whitelist before building the query.
- Format datetimes in Java unless the database must do the formatting.
When it happens
Trigger: format( x.ts as '...' ) (or the criteria equivalent) with unsupported letters: u or uuuu years, Q/q quarters, L standalone month, c localized day, A milli-of-day, n nanos, or a letter repeated more times than allowed (e.g. six+ E's, seven+ S's); unbalanced quotes also fail to match.
Common situations: Copying a working java.time DateTimeFormatter pattern straight into HQL; quarter-based reporting patterns (QQ yyyy); strftime-style tokens (%Y-%m) or moment.js patterns pasted into the format string.
Related errors
- Insert conflict 'do update' clause with constraint name is n
- field type not supported on Derby: " + unit
- format() function not supported on Derby
- field type not supported on Derby: " + unit
- format() function not supported on Derby
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/ec72246fd28691d4.
Report an issue: GitHub.