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

  1. Correct the extends attributes or setSuperclass calls so each entity extends its real parent and exactly one root exists
  2. Search all mapping files for duplicate entity names that made two classes point at each other
  3. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/399eeb98b969589c. Report an issue: GitHub.