{"record":{"id":"15f71198c4c278ab","repo":"hibernate/hibernate-orm","slug":"mapped-superclass-may-not-specify-a-table","errorCode":null,"errorMessage":"Mapped superclass '{}' may not specify a '@Table'","messagePattern":"Mapped superclass '(.+?)' may not specify a '@Table'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java","lineNumber":291,"sourceCode":"\n\tprivate static void handleImport(ClassDetails annotatedClass, MetadataBuildingContext context) {\n\t\tif ( annotatedClass.hasDirectAnnotationUsage( Imported.class ) ) {\n\t\t\tfinal String qualifiedName = annotatedClass.getName();\n\t\t\tfinal String name = unqualify( qualifiedName );\n\t\t\tfinal String rename = annotatedClass.getDirectAnnotationUsage( Imported.class ).rename();\n\t\t\tcontext.getMetadataCollector().addImport( rename.isBlank() ? name : rename, qualifiedName );\n\t\t}\n\t}\n\n\tprivate static void detectMappedSuperclassProblems(ClassDetails annotatedClass) {\n\t\tif ( isMappedSuperclass( annotatedClass ) ) {\n\t\t\t// @Entity and @MappedSuperclass on the same class leads to NPE down the road\n\t\t\tif ( isEntity( annotatedClass ) ) {\n\t\t\t\tthrow new AnnotationException( \"Type '\" + annotatedClass.getName()\n\t\t\t\t\t\t+ \"' is annotated both '@Entity' and '@MappedSuperclass'\" );\n\t\t\t}\n\t\t\tif ( annotatedClass.hasDirectAnnotationUsage( Table.class ) ) {\n\t\t\t\tthrow new AnnotationException( \"Mapped superclass '\" + annotatedClass.getName()\n\t\t\t\t\t\t+ \"' may not specify a '@Table'\" );\n\t\t\t}\n\t\t\tif ( annotatedClass.hasDirectAnnotationUsage( Inheritance.class ) ) {\n\t\t\t\tthrow new AnnotationException( \"Mapped superclass '\" + annotatedClass.getName()\n\t\t\t\t\t\t+ \"' may not specify an '@Inheritance' mapping strategy\" );\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static void bindTypeDescriptorRegistrations(\n\t\t\tAnnotationTarget annotatedElement,\n\t\t\tMetadataBuildingContext context) {\n\t\tfinal var managedBeanRegistry = context.getBootstrapContext().getManagedBeanRegistry();\n\t\tfinal var sourceModelContext = modelsContext( context );\n\n\t\tannotatedElement.forEachAnnotationUsage(\n\t\t\t\tJavaTypeRegistration.class,\n\t\t\t\tsourceModelContext,","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java#L273-L309","documentation":"A '@MappedSuperclass' declares a direct '@Table' annotation. A mapped superclass has no table of its own — its mappings are folded into each subclass's table — so an explicit @Table is meaningless and rejected at bootstrap. Table settings belong to the concrete @Entity at the root of each subclass mapping.","triggerScenarios":"'@MappedSuperclass @Table(name = \"base\")' on an abstract class; converting an entity to a superclass without deleting its @Table; generated code emitting a table on every persistent-looking class.","commonSituations":"Refactoring a concrete entity into a shared base and leaving '@Table' behind; tools/templates that annotate all persistent classes with @Table; misunderstanding that @MappedSuperclass is not a table-backed type.","solutions":["Remove '@Table' from the mapped superclass.","Declare '@Table(name = ...)' on each concrete @Entity subclass instead.","If the base really needs its own table, it must be an '@Entity' with an inheritance strategy, not a '@MappedSuperclass'."],"exampleFix":"// before\n@MappedSuperclass\n@Table(name = \"person_base\") // -> error\npublic abstract class BaseEntity { @Id Long id; }\n\n// after\n@MappedSuperclass\npublic abstract class BaseEntity { @Id Long id; }\n\n@Entity\n@Table(name = \"person\")\nclass Person extends BaseEntity { ... }","handlingStrategy":"validation","validationCode":"// Guard: mapped superclasses must not declare @Table\nif (cls.isAnnotationPresent(MappedSuperclass.class)\n        && cls.isAnnotationPresent(Table.class)) {\n    throw new IllegalStateException(\n        cls.getName() + \": @MappedSuperclass may not declare @Table\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Metadata md = sources.buildMetadata();\n} catch (AnnotationException e) {\n    // 'may not specify a @Table' -> move the @Table to each concrete @Entity\n    throw newConfigurationException(\"Illegal @Table on superclass\", e);\n}","preventionTips":["@Table belongs on concrete entities only; base classes carry no table mapping.","Add a class-annotation lint rule for @MappedSuperclass types in CI."],"tags":["hibernate","jpa","mapped-superclass","table-annotation","orm-mapping"],"backgroundTag":"mapped-superclass-misuse","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}