{"record":{"id":"069f6362b05c9f36","repo":"hibernate/hibernate-orm","slug":"entity-class-classname-is-annotated-concret","errorCode":null,"errorMessage":"Entity class '${className}' is annotated '@ConcreteProxy' but it is not the root of the entity inheritance hierarchy","messagePattern":"Entity class '(.+?)' is annotated '@ConcreteProxy' but it is not the root of the entity inheritance hierarchy","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java","lineNumber":1829,"sourceCode":"\t\t\telse {\n\t\t\t\tfinal String discriminatorTypeName = discriminator.getType().getName();\n\t\t\t\treturn switch ( discriminatorTypeName ) {\n\t\t\t\t\tcase \"string\" -> name; //Spec compliant\n\t\t\t\t\tcase \"integer\"-> String.valueOf( name.hashCode() ); // TODO: pretty nasty, should we just deprecate/disallow this?\n\t\t\t\t\tdefault -> throw new MappingException( \"Entity '\" + name + \"' must explicitly specify its '@DiscriminatorValue'\" );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\treturn discriminatorValue.value();\n\t\t}\n\t}\n\n\tprivate void bindConcreteProxy() {\n\t\tfinal var concreteProxy = annotatedClass.getAnnotationUsage( ConcreteProxy.class, modelsContext() );\n\t\tif ( concreteProxy != null ) {\n\t\t\tif ( persistentClass.getSuperclass() != null ) {\n\t\t\t\tthrow new AnnotationException( \"Entity class '\" + persistentClass.getClassName()\n\t\t\t\t\t\t+  \"' is annotated '@ConcreteProxy' but it is not the root of the entity inheritance hierarchy\" );\n\t\t\t}\n\t\t\tpersistentClass.getRootClass().setConcreteProxy( true );\n\t\t}\n\t}\n\n\tprivate void bindSqlRestriction() {\n\t\tfinal var restriction = extractSQLRestriction( annotatedClass );\n\t\tif ( restriction != null ) {\n\t\t\twhere = restriction.value();\n\t\t}\n\t}\n\n\tprivate SQLRestriction extractSQLRestriction(ClassDetails classDetails) {\n\t\tfinal var modelsContext = modelsContext();\n\t\tfinal var fromClass = getOverridableAnnotation( classDetails, SQLRestriction.class, context );\n\t\tif ( fromClass != null ) {\n\t\t\treturn fromClass;","sourceCodeStart":1811,"sourceCodeEnd":1847,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java#L1811-L1847","documentation":"Error \"Entity class '${className}' is annotated '@ConcreteProxy' but it is not the root of the entity inheritance hierarchy\" thrown in hibernate/hibernate-orm.","triggerScenarios":"An annotation restricted to the root of an inheritance hierarchy is placed on a subclass (or the hierarchy rules are otherwise violated).","commonSituations":"SINGLE_TABLE/JOINED hierarchies where @Table, @DiscriminatorColumn, @DiscriminatorFormula, @Cache, @Immutable, @Id or @Version are declared on the wrong class of the hierarchy.","solutions":["Move @ConcreteProxy to the root class of the entity inheritance hierarchy."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}