hibernate/hibernate-orm · error · HibernateException
Unknown query type for registering as named query (%s) : %s
Error message
Unknown query type for registering as named query (%s) : %s
What it means
When registering an existing query object as a named query, Hibernate's runtime dispatch only accepts org.hibernate.query.Statement / MutationOrSelectionQuery implementations — i.e. query objects created by the same Hibernate factory. Any other TypedQuery implementation (another JPA provider's, a wrapper, a mock) falls through the instanceof chain and triggers HibernateException 'Unknown query type'.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java:1181
@Override
public void addNamedQuery(@Nonnull String name, @Nonnull Query query) {
if ( query instanceof TypedQuery<?> typedQuery ) {
addNamedQuery( name, typedQuery );
}
else if ( query instanceof Statement statement ) {
addNamedStatement( name, statement );
}
else if ( query instanceof MutationOrSelectionQuery statementOrTypedQuery ) {
if ( statementOrTypedQuery.isMutationQuery() ) {
addNamedStatement( name, statementOrTypedQuery.asMutationQuery() );
}
else {
addNamedQuery( name, statementOrTypedQuery.asSelectionQuery() );
}
}
else {
throw new HibernateException( String.format( ROOT,
"Unknown query type for registering as named query (%s) : %s",
name,
query
) );
}
}
@Override
@Nonnull
public <R> TypedQueryReference<R> addNamedQuery(@Nonnull String name, @Nonnull TypedQuery<R> query) {
return getNamedObjectRepository().registerNamedQuery( name, query );
}
@Override
@Nonnull
public StatementReference addNamedStatement(@Nonnull String name, @Nonnull Statement statement) {
return getNamedObjectRepository().registerNamedMutation( name, statement );
}View on GitHub (pinned to fad1729dce)
Solutions
- Register a query created by the same factory: rebuild it via sessionFactory.createSelectionQuery(...)/createMutationQuery(...) and register that
- If you hold a wrapped query, unwrap to the Hibernate type first: query.unwrap(org.hibernate.query.Query.class)
- For selection vs mutation, branch on instanceof SelectionQuery/MutationQuery and pass the unwrapped Statement form
- In tests, register a real query built from a test EMF instead of a mock
Example fix
// before
typedQuery = wrapForMetrics(em.createQuery(jpql));
sessionFactory.addNamedQuery("findAll", typedQuery); // wrapper is not a Statement -> throws
// after
org.hibernate.query.SelectionQuery<Order> hq =
sessionFactory.createSelectionQuery(jpql, Order.class);
sessionFactory.addNamedQuery("findAll", hq); Defensive patterns
Strategy: type-guard
Validate before calling
if (query instanceof org.hibernate.query.SelectionQuery<?> sq) {
sessionFactory.addNamedQuery(name, sq);
} else if (query instanceof org.hibernate.query.MutationQuery mq) {
sessionFactory.addNamedQuery(name, mq);
} else {
throw new IllegalArgumentException("Query is not a Hibernate Statement: " + query.getClass());
} Type guard
static boolean isRegistrable(TypedQuery<?> q) {
return q instanceof org.hibernate.query.Statement;
} Try / catch
try {
sessionFactory.addNamedQuery(name, typedQuery);
} catch (HibernateException e) {
if (e.getMessage().contains("Unknown query type")) {
// re-create the query from this factory and register that instead
var rebuilt = sessionFactory.createSelectionQuery(jpql, resultClass);
sessionFactory.addNamedQuery(name, rebuilt);
} else throw e;
} Prevention
- Only register query objects produced by the same SessionFactory
- Unwrap decorated queries to org.hibernate.query.Query before registering
- In tests, build real queries from a test EMF instead of mocking TypedQuery
When it happens
Trigger: Calling sessionFactory.addNamedQuery(name, typedQuery) where the TypedQuery was not produced by this Hibernate SessionFactory: a query from a different JPA provider, a delegating wrapper TypedQuery, or a stub in tests. Also passing a StoredProcedureQuery or custom TypedQuery subtype.
Common situations: Multi-provider code or abstraction layers (e.g. a generic DAO) that mix vendor query objects; unit tests registering Mockito mocks of TypedQuery; frameworks that wrap queries for instrumentation/tenancy and then try to re-register the wrapper.
Related errors
- immutable global instance of LockOptions
- null is not a valid query name
- Named query definition is null
- Named query definition name is null: %s
- Duplicate named query '%s'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/1bd3775f1e3a8e76.
Report an issue: GitHub.