hibernate/hibernate-orm · error · AnnotationException
Mapped superclass '{}' may not specify a '@Table'
Error message
Mapped superclass '{}' may not specify a '@Table' What it means
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.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java:291
private static void handleImport(ClassDetails annotatedClass, MetadataBuildingContext context) {
if ( annotatedClass.hasDirectAnnotationUsage( Imported.class ) ) {
final String qualifiedName = annotatedClass.getName();
final String name = unqualify( qualifiedName );
final String rename = annotatedClass.getDirectAnnotationUsage( Imported.class ).rename();
context.getMetadataCollector().addImport( rename.isBlank() ? name : rename, qualifiedName );
}
}
private static void detectMappedSuperclassProblems(ClassDetails annotatedClass) {
if ( isMappedSuperclass( annotatedClass ) ) {
// @Entity and @MappedSuperclass on the same class leads to NPE down the road
if ( isEntity( annotatedClass ) ) {
throw new AnnotationException( "Type '" + annotatedClass.getName()
+ "' is annotated both '@Entity' and '@MappedSuperclass'" );
}
if ( annotatedClass.hasDirectAnnotationUsage( Table.class ) ) {
throw new AnnotationException( "Mapped superclass '" + annotatedClass.getName()
+ "' may not specify a '@Table'" );
}
if ( annotatedClass.hasDirectAnnotationUsage( Inheritance.class ) ) {
throw new AnnotationException( "Mapped superclass '" + annotatedClass.getName()
+ "' may not specify an '@Inheritance' mapping strategy" );
}
}
}
private static void bindTypeDescriptorRegistrations(
AnnotationTarget annotatedElement,
MetadataBuildingContext context) {
final var managedBeanRegistry = context.getBootstrapContext().getManagedBeanRegistry();
final var sourceModelContext = modelsContext( context );
annotatedElement.forEachAnnotationUsage(
JavaTypeRegistration.class,
sourceModelContext,View on GitHub (pinned to fad1729dce)
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'.
Example fix
// before
@MappedSuperclass
@Table(name = "person_base") // -> error
public abstract class BaseEntity { @Id Long id; }
// after
@MappedSuperclass
public abstract class BaseEntity { @Id Long id; }
@Entity
@Table(name = "person")
class Person extends BaseEntity { ... } Defensive patterns
Strategy: validation
Validate before calling
// Guard: mapped superclasses must not declare @Table
if (cls.isAnnotationPresent(MappedSuperclass.class)
&& cls.isAnnotationPresent(Table.class)) {
throw new IllegalStateException(
cls.getName() + ": @MappedSuperclass may not declare @Table");
} Try / catch
try {
Metadata md = sources.buildMetadata();
} catch (AnnotationException e) {
// 'may not specify a @Table' -> move the @Table to each concrete @Entity
throw newConfigurationException("Illegal @Table on superclass", e);
} Prevention
- @Table belongs on concrete entities only; base classes carry no table mapping.
- Add a class-annotation lint rule for @MappedSuperclass types in CI.
When it happens
Trigger: '@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.
Common situations: 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.
Related errors
- Type '{}' is annotated both '@Entity' and '@MappedSuperclass
- Mapped superclass '{}' may not specify an '@Inheritance' map
- Class '<componentClassName>' is an '@Embeddable' type and ma
- Property '<propertyName>' may not be annotated '@BatchSize'
- One to many association '<propertyName>' was annotated '@Col
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/15f71198c4c278ab.
Report an issue: GitHub.