{"record":{"id":"380a88a97d48b499","repo":"hibernate/hibernate-orm","slug":"cannot-instantiate-query-result-type-found-no-mat","errorCode":null,"errorMessage":"Cannot instantiate query result type, found no matching constructor","messagePattern":"Cannot instantiate query result type, found no matching constructor","errorType":"exception","errorClass":"InstantiationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/results/internal/RowTransformerConstructorImpl.java","lineNumber":46,"sourceCode":"\n\tpublic RowTransformerConstructorImpl(\n\t\t\tClass<T> type,\n\t\t\tTupleMetadata tupleMetadata,\n\t\t\tTypeConfiguration typeConfiguration) {\n\t\tthis.type = type;\n\t\tassert tupleMetadata != null : \"TupleMetadata must not be null\";\n\t\tfinal List<TupleElement<?>> elements = tupleMetadata.getList();\n\t\tfinal List<Class<?>> argumentTypes = elements.stream()\n\t\t\t\t.map( RowTransformerConstructorImpl::resolveElementJavaType )\n\t\t\t\t.collect( toList() );\n\t\tif ( argumentTypes.size() == 1 && argumentTypes.get( 0 ) == null ) {\n\t\t\t// Can not (properly) resolve constructor for single null element\n\t\t\tthrow new InstantiationException( \"Cannot instantiate query result type, argument types are unknown \", type );\n\t\t}\n\n\t\tconstructor = findMatchingConstructor( type, argumentTypes, typeConfiguration );\n\t\tif ( constructor == null ) {\n\t\t\tthrow new InstantiationException( \"Cannot instantiate query result type, found no matching constructor\", type );\n\t\t}\n\t\tconstructor.setAccessible( true );\n\t}\n\n\tprivate static Class<?> resolveElementJavaType(TupleElement<?> element) {\n\t\tif ( element instanceof SqmExpressibleAccessor<?> accessor ) {\n\t\t\tfinal SqmExpressible<?> expressible = accessor.getExpressible();\n\t\t\tif ( expressible != null && expressible.getExpressibleJavaType() != null ) {\n\t\t\t\treturn expressible.getExpressibleJavaType().getJavaTypeClass();\n\t\t\t}\n\t\t}\n\n\t\treturn element.getJavaType();\n\t}\n\n\t@Override\n\tpublic T transformRow(Object[] row) {\n\t\ttry {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/results/internal/RowTransformerConstructorImpl.java#L28-L64","documentation":"Thrown while building RowTransformerConstructorImpl: the tuple element Java types were resolved, but no constructor of the requested result class matches them (wrong count, order, or types). In the standard SQM path this is caught at ConcreteSqmSelectQueryPlan:371 and the checking transformer takes over, so you frequently see the QueryTypeMismatchException of error 3186 at execution time instead; the raw message surfaces through construction paths without that catch (e.g. ConcreteSqmSelectQueryPlan:339).","triggerScenarios":"`em.createQuery(\"select e.name, e.salary from Employee e\", NameSalaryDto.class)` where NameSalaryDto has no `(String, BigDecimal)` constructor; DTO constructor expects `int`/`Integer` but selection resolves to `Long`; arguments selected in a different order than the constructor parameters.","commonSituations":"DTO and entity drift after refactors; database dialect changes that alter the Java type of an aggregate (`count` returning Long vs Integer); adding a column to the projection without updating the DTO.","solutions":["Add a constructor to the result class whose parameter list matches the selected expressions exactly (count, order, types) - prefer boxed types matching Hibernate's resolution (e.g. Long for ids and counts)","Print the tuple types first by querying with `Object[].class`, then write the constructor to fit","If the class is out of your control, switch to `select new your.Dto(...)`-style injection of an adaptable DTO, or query Tuple/Object[] and map manually"],"exampleFix":"// before\npublic NameSalaryDto(String name, int salary) { ... }\nList<NameSalaryDto> l = em.createQuery(\"select e.name, e.salary from Employee e\", NameSalaryDto.class).getResultList(); // salary resolves to BigDecimal\n// after\npublic NameSalaryDto(String name, java.math.BigDecimal salary) { ... }","handlingStrategy":"validation","validationCode":"// Print the resolved tuple types, then write the constructor to match exactly\nObject[] row = em.createQuery(\"select e.name, e.salary from Employee e\", Object[].class).setMaxResults(1).getSingleResult();\nArrays.stream(row).forEach(v -> System.out.println(v == null ? \"null\" : v.getClass().getName()));","typeGuard":null,"tryCatchPattern":"catch (org.hibernate.InstantiationException e) { if (e.getMessage().contains(\"no matching constructor\")) { /* align DTO ctor with printed tuple types */ } throw e; }","preventionTips":["Keep DTO constructors generated next to the query (mapstruct/codegen) so they cannot drift","Prefer boxed types and BigDecimal/Long for numerics; JDBC aggregates are rarely int","After schema or dialect changes, re-run projection probe tests that assert tuple Java types"],"tags":["hql","jpql","dto","constructor","type-mismatch","result-type"],"backgroundTag":"query-result-type-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}