quarkusio/quarkus · error · IllegalArgumentException

Must be a named query!

Error message

Must be a named query!

What it means

extractNamedQueryName is used for mutation operations (update/delete) that must reference a named query. The method validates that the query string starts with '#' (Panache's named-query marker); any other string is rejected with this IllegalArgumentException.

Source

Thrown at extensions/panache/hibernate-orm-panache-common/runtime/src/main/java/io/quarkus/hibernate/orm/panache/common/runtime/AbstractJpaOperations.java:356

    }

    public long count(Class<?> entityClass, String query, Parameters params) {
        return count(entityClass, query, params.map());
    }

    private SelectionQuery<?> extractNamedSelectionQuery(Class<?> entityClass, String query) {
        String namedQueryName = extractNamedQueryName(entityClass, query);
        return getSession(entityClass).createNamedSelectionQuery(namedQueryName);
    }

    private MutationQuery extractNamedMutationQuery(Class<?> entityClass, String query) {
        String namedQueryName = extractNamedQueryName(entityClass, query);
        return getSession(entityClass).createNamedMutationQuery(namedQueryName);
    }

    private String extractNamedQueryName(Class<?> entityClass, String query) {
        if (!PanacheJpaUtil.isNamedQuery(query))
            throw new IllegalArgumentException("Must be a named query!");

        String namedQueryName = query.substring(1);
        NamedQueryUtil.checkNamedQuery(entityClass, namedQueryName);
        return namedQueryName;
    }

    public boolean exists(Class<?> entityClass) {
        return count(entityClass) > 0;
    }

    public boolean exists(Class<?> entityClass, String query, Object... params) {
        return count(entityClass, query, params) > 0;
    }

    public boolean exists(Class<?> entityClass, String query, Map<String, Object> params) {
        return count(entityClass, query, params) > 0;
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Prefix the query string with '#' to indicate a named query: update("#Person.markInactive")
  2. Define the mutation as an @NamedQuery on the entity
  3. Use a different API method that accepts literal HQL if a named query is not available

Example fix

// before
repo.update("update Person set active = false");
// after
repo.update("#Person.deactivateAll");
Defensive patterns

Strategy: validation

Validate before calling

if (!query.startsWith("#")) {
    throw new IllegalArgumentException("This operation only accepts named queries; prefix with '#': #" + query);
}

Type guard

boolean isNamedQuery(String q) { return q != null && q.startsWith("#"); }

Try / catch

try {
    repo.update(query);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().equals("Must be a named query!")) {
        // use "#" + name of an @NamedQuery
    } else throw e;
}

Prevention

When it happens

Trigger: Calling update("...") or delete("...") style operations that route through namedQueryName/extractNamedQueryName with a literal HQL string instead of a '#'-prefixed named query name.

Common situations: Confusing the API surface that accepts arbitrary HQL with the named-query-only variant; forgetting the leading '#' when switching from literal HQL to a named query.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/fa9d918b687f04c1. Report an issue: GitHub.