{"record":{"id":"9c167cacb595a101","repo":"hibernate/hibernate-orm","slug":"error-performing-the-dynamic-instantiation","errorCode":null,"errorMessage":"Error performing the dynamic instantiation","messagePattern":"Error performing the dynamic instantiation","errorType":"exception","errorClass":"InstantiationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/BeanInjectorField.java","lineNumber":27,"sourceCode":"import org.hibernate.query.sqm.sql.internal.InstantiationException;\n\n/**\n * @author Steve Ebersole\n */\nclass BeanInjectorField<T> implements BeanInjector<T> {\n\tprivate final Field field;\n\n\tpublic BeanInjectorField(Field field) {\n\t\tthis.field = field;\n\t}\n\n\t@Override\n\tpublic void inject(T target, Object value) {\n\t\ttry {\n\t\t\tfield.set( target, value );\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new InstantiationException( \"Error performing the dynamic instantiation\", e );\n\t\t}\n\t}\n}\n","sourceCodeStart":9,"sourceCodeEnd":31,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/BeanInjectorField.java#L9-L31","documentation":"During bean-injection style dynamic instantiation ('select new com.acme.Foo(...) ...' where Hibernate injects values by setter/field because no matching constructor exists), BeanInjectorField.inject() calls Field.set(target, value) under reflection. Any failure - most often the selected value's type not fitting the field's type, or the field being inaccessible/final - is wrapped in InstantiationException('Error performing the dynamic instantiation') with the original exception as cause.","triggerScenarios":"A dynamic-instantiation query whose aliased argument type differs from the target field's type (e.g. field is int but the column assembles as Long/BigDecimal, or field is an enum but value is String); the target field is final; field access blocked by Java module rules (setAccessible fails).","commonSituations":"DTO field types not matching JDBC/Hibernate return types (primitives vs wrappers, BigDecimal vs long); refactorings that change DTO field types while the query stays the same; classes in closed modules or non-open JPMS packages; records or immutable classes whose fields cannot be set reflectively.","solutions":["Read the cause chain - it names the exact reflection failure (IllegalArgumentException 'field type mismatch' is the classic one).","Align the DTO field type with the assembled type (use wrapper/object types: Long, String, BigDecimal; avoid primitives).","Prefer a constructor expression with an explicit matching constructor over field injection - it gives clearer errors and compile-time-ish safety.","Ensure the class is public with non-final fields (or setters), and that reflection into its package is permitted."],"exampleFix":"// before\npublic class SalesDto { private int total; } // column SUM(...) assembles as Long/BigDecimal\nem.createQuery(\"select new com.acme.SalesDto(sum(l.amount) as total) from Line l\", SalesDto.class);\n// -> InstantiationException: Can not set int field to Long\n\n// after\npublic class SalesDto { private Long total; public Long getTotal() { return total; } }","handlingStrategy":"try-catch","validationCode":"// At startup, verify each DTO field type accepts the assembled type\nfor (Field f : SalesDto.class.getDeclaredFields()) {\n    if (f.getType() == int.class || f.getType() == long.class || f.getType() == double.class) {\n        throw new IllegalStateException(\"primitive field \" + f.getName()\n            + \" will not accept null aggregate results - use wrapper type\");\n    }\n}","typeGuard":"// Reflective guard: every aliased select item must be assignable to its target field\nstatic boolean fieldAccepts(Class<?> dto, String alias, Class<?> assembled) {\n    try {\n        return dto.getDeclaredField(alias).getType().isAssignableFrom(assembled);\n    } catch (NoSuchFieldException e) { return false; }\n}","tryCatchPattern":"try {\n    List<SalesDto> rows = q.getResultList();\n} catch (org.hibernate.query.sqm.sql.internal.InstantiationException e) {\n    Throwable cause = e.getCause();\n    // cause is the reflection failure; align DTO field types with the assembled types\n}","preventionTips":["Use wrapper/object types (Long, Integer, BigDecimal, String) in injection DTOs, never primitives.","Prefer explicit constructor expressions over field injection - failures become visible signature mismatches.","Smoke-test every dynamic-instantiation query at startup against data with nulls."],"tags":["hibernate","orm","dynamic-instantiation","reflection","dto","query-projection"],"backgroundTag":"dynamic-instantiation-injection-failure","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}