hibernate/hibernate-orm · error · MappingException
Circular inheritance mapping: '" + subclass.getEntityName()
Error message
Circular inheritance mapping: '" + subclass.getEntityName() + "' will have itself as superclass when extending '" + getEntityName() + "'
What it means
Hibernate detected that an entity inheritance hierarchy forms a cycle. addSubclass() walks the receiver's superclass chain; if the subclass being added already appears as an ancestor, adding it would produce a class that is its own superclass, so the mapping is rejected. This is a structural mapping defect, not a runtime data problem.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java:225
public void setDynamicInsert(boolean dynamicInsert) {
this.dynamicInsert = dynamicInsert;
}
public void setDynamicUpdate(boolean dynamicUpdate) {
this.dynamicUpdate = dynamicUpdate;
}
public String getDiscriminatorValue() {
return discriminatorValue;
}
public void addSubclass(Subclass subclass) throws MappingException {
// inheritance cycle detection (paranoid check)
PersistentClass superclass = getSuperclass();
while ( superclass != null ) {
if ( subclass.getEntityName().equals( superclass.getEntityName() ) ) {
throw new MappingException(
"Circular inheritance mapping: '"
+ subclass.getEntityName()
+ "' will have itself as superclass when extending '"
+ getEntityName()
+ "'"
);
}
superclass = superclass.getSuperclass();
}
subclasses.add( subclass );
}
public boolean hasSubclasses() {
return !subclasses.isEmpty();
}
public int getSubclassSpan() {
int span = subclasses.size();View on GitHub (pinned to fad1729dce)
Solutions
- Correct the extends attributes or setSuperclass calls so each entity extends its real parent and exactly one root exists
- Search all mapping files for duplicate entity names that made two classes point at each other
- When building the model programmatically, assert the superclass chain terminates before calling addSubclass
Example fix
// before <class name="com.acme.A"/> <subclass name="com.acme.B" extends="com.acme.A"/> <!-- stale file: <subclass name="com.acme.A" extends="com.acme.B"/> --> // after <!-- delete the stale mapping; keep a single acyclic hierarchy --> <class name="com.acme.A"/> <subclass name="com.acme.B" extends="com.acme.A"/>
Defensive patterns
Strategy: validation
Validate before calling
static void assertAcyclicHierarchy(Iterable<PersistentClass> classes) {
for (PersistentClass pc : classes) {
Set<String> seen = new HashSet<>();
for (PersistentClass s = pc; s != null; s = s.getSuperclass()) {
if (!seen.add(s.getEntityName())) {
throw new IllegalStateException(s.getEntityName()); // cycle
}
}
}
} Try / catch
try { metadata.buildSessionFactory(); }
catch (MappingException e) {
if (e.getMessage().contains("Circular inheritance")) {
// open the two mapping files named in the message and fix the extends attributes
}
throw e;
} Prevention
- Derive mapping hierarchy from the Java class hierarchy instead of hand-written extends attributes
- Run a SessionFactory build in a unit test so structural errors fail the build, not production startup
When it happens
Trigger: hbm.xml where subclass A declares extends=B and subclass B declares extends=A; programmatic mapping code that wires setSuperclass/addSubclass in a loop; metamodel manipulators that copy superclass links between PersistentClass instances.
Common situations: Hand-edited XML mappings spread across many files; dynamic model assembly where the parent link comes from external data; importing mappings from another project with conflicting entity names.
Related errors
- subclass key mapping has wrong number of columns: " + getEnt
- Could not resolve attribute '%s' of '%s' due to the attribut
- Illegal discriminator type: {discriminatorType}
- Could not parse discriminator value '{discriminatorValue}' a
- Discriminator formulas on joined inheritance hierarchies not
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/399eeb98b969589c.
Report an issue: GitHub.