{"record":{"id":"65d035937e94a6bd","repo":"hibernate/hibernate-orm","slug":"target-type-s-is-not-an-entity","errorCode":null,"errorMessage":"Target type '%s' is not an entity","messagePattern":"Target type '(.+?)' is not an entity","errorType":"exception","errorClass":"SemanticException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/insert/AbstractSqmInsertStatement.java","lineNumber":124,"sourceCode":"//\t\t\tif ( insertionTargetPaths.get( i ).getJavaTypeDescriptor() != expression.getNodeJavaType() ) {\n//\t\t\t\tthrow new SemanticException(\n//\t\t\t\t\t\tString.format(\n//\t\t\t\t\t\t\t\t\"Expected insert attribute type [%s] did not match Query selection type [%s] at selection index [%d]\",\n//\t\t\t\t\t\t\t\tinsertionTargetPaths.get( i ).getJavaTypeDescriptor().getTypeName(),\n//\t\t\t\t\t\t\t\texpression.getNodeJavaType().getTypeName(),\n//\t\t\t\t\t\t\t\ti\n//\t\t\t\t\t\t),\n//\t\t\t\t\t\thqlString,\n//\t\t\t\t\t\tnull\n//\t\t\t\t);\n//\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void setTarget(@Nonnull JpaRoot<T> root) {\n\t\tif ( root.getModel() instanceof SqmPolymorphicRootDescriptor<?> ) {\n\t\t\tthrow new SemanticException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\"Target type '%s' is not an entity\",\n\t\t\t\t\t\t\troot.getModel().getHibernateEntityName()\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\tsuper.setTarget( root );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic List<SqmPath<?>> getInsertionTargetPaths() {\n\t\treturn insertionTargetPaths == null\n\t\t\t\t? Collections.emptyList()\n\t\t\t\t: Collections.unmodifiableList( insertionTargetPaths );\n\t}\n\n\t@Nonnull","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/insert/AbstractSqmInsertStatement.java#L106-L142","documentation":"AbstractSqmInsertStatement.setTarget throws SemanticException when the target root's model is a SqmPolymorphicRootDescriptor — Hibernate's virtual entity type for a Java type (usually an interface or non-entity superclass) that matches multiple mapped entities. An INSERT needs one concrete table to write to; a polymorphic reference like `PaymentMethod` (implemented by CreditCard and BankTransfer) designates several tables, so Hibernate refuses it as an insert target.","triggerScenarios":"HQL `insert into PaymentMethod (amount) select ...` where PaymentMethod is an interface/superclass mapped polymorphically across entities; criteria `insert.setTarget( root )` where root was built from `metamodel.entity(SomeInterface.class)` and the metamodel resolved it to a polymorphic descriptor; `from MyInterface` style roots reused as insert targets.","commonSituations":"Domain models with interface-based polymorphism where the interface is what the code references everywhere; porting SELECT queries (which DO support polymorphic roots — they are split into per-entity queries) to INSERT statements and assuming the same support; code that derives the insert target type generically from a variable of a shared supertype.","solutions":["Target one concrete entity: `insert into CreditCard (amount) select ...`","If several subtypes must receive rows, issue one INSERT per concrete entity type","Validate the target before building the statement: `root.getModel().getPersistenceType() == PersistenceType.ENTITY` plus checking it is not a polymorphic virtual descriptor","In generic code, resolve the actual entity: use the concrete subclass or `sessionFactory.getMetamodel().entity(concreteClass)`"],"exampleFix":"// before\nsession.createQuery(\"insert into PaymentMethod (amount) select p.amount from OldPayment p\").executeUpdate();\n\n// after\nsession.createQuery(\"insert into CreditCard (amount) select p.amount from OldPayment p\").executeUpdate();","handlingStrategy":"validation","validationCode":"import jakarta.persistence.metamodel.Type;\n\nvar model = root.getModel();\nif (model.getPersistenceType() != Type.PersistenceType.ENTITY\n        || model instanceof org.hibernate.query.sqm.tree.spi.domain.SqmPolymorphicRootDescriptor) {\n    throw new IllegalArgumentException(\"Insert target must be a single concrete entity: \" + model);\n}","typeGuard":"static boolean isConcreteEntityTarget(jakarta.persistence.metamodel.EntityType<?> t) {\n    return !(t instanceof org.hibernate.query.sqm.tree.spi.domain.SqmPolymorphicRootDescriptor<?>);\n}","tryCatchPattern":"try { insert.executeUpdate(); }\ncatch (org.hibernate.query.SemanticException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"is not an entity\")) {\n        // re-target a concrete entity class and rebuild the statement\n    } else throw e;\n}","preventionTips":["Insert only into concrete @Entity classes","Do not reuse polymorphic roots (interfaces/superclasses of several entities) as DML targets","In generic DAOs, resolve the entity name via the metamodel and assert it maps to one table"],"tags":["hibernate","hql","insert","polymorphism","entity-type","semantic-error"],"backgroundTag":"polymorphic-entity-reference","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}