hibernate/hibernate-orm · error · TransformationException

Error transforming element-collection :

Error message

Error transforming element-collection : 

What it means

Thrown by Hibernate 6's legacy-hbm-to-mapping.xml transformer (HbmXmlTransformer) when transforming a collection mapped with <element/> or <composite-element/> (an element-collection) fails. The TransformationException wraps the real cause and attaches the Origin (source file/position) of the offending mapping. The outer message only names the collection property; the actionable detail is always in getCause().

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/jaxb/hbm/transform/HbmXmlTransformer.java:2210

				}
			}
			else if ( hbmAttributeMapping instanceof JaxbHbmAnyAssociationType any ) {
				try {
					final var propertyInfo = managedTypeInfo.propertyInfoMap().get( any.getName() );
					attributes.getAnyMappingAttributes().add( transformAnyAttribute( any, propertyInfo ) );
				}
				catch (Exception e) {
					throw new TransformationException( "Error transforming <any/> : " + any.getName(), e, origin() );
				}
			}
			else if ( hbmAttributeMapping instanceof PluralAttributeInfo hbmCollection ) {
				final var propertyInfo = managedTypeInfo.propertyInfoMap().get( hbmCollection.getName() );
				if ( hbmCollection.getElement() != null || hbmCollection.getCompositeElement() != null ) {
					try {
						attributes.getElementCollectionAttributes().add( transformElementCollection( roleBase, hbmCollection, propertyInfo ) );
					}
					catch (Exception e) {
						throw new TransformationException( "Error transforming element-collection : " + hbmCollection.getName(), e, origin() );
					}
				}
				else if ( hbmCollection.getOneToMany() != null ) {
					try {
						attributes.getOneToManyAttributes().add( transformOneToMany( hbmCollection, propertyInfo ) );
					}
					catch (Exception e) {
						throw new TransformationException( "Error transforming one-to-many : " + hbmCollection.getName(), e, origin() );
					}
				}
				else if ( hbmCollection.getManyToMany() != null ) {
					try {
						if ( hbmCollection.getManyToMany().isUnique() ) {
							attributes.getOneToManyAttributes().add( transformManyToManyToOneToMany( hbmCollection, propertyInfo ) );
						}
						else {
							attributes.getManyToManyAttributes().add( transformManyToMany( hbmCollection, propertyInfo ) );
						}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Inspect exception.getCause() first - it carries the real reason (unknown type, ClassNotFound, invalid column); the outer message only identifies the collection name
  2. Verify every <element type="..."> resolves: custom types must be registered (TypeContributor/service registry) on the classpath used for transformation
  3. Check each <composite-element class="..."> names a loadable class
  4. Fix the offending collection in the hbm.xml and re-run the transformation
  5. If the construct is valid hbm but the transformer cannot handle it, leave that mapping as native hbm.xml - Hibernate 6 still binds hbm.xml directly without transformation

Example fix

<!-- before -->
<set name="labels" table="labels">
    <element type="com.acme.LabelTypo" column="label"/>
</set>

<!-- after -->
<set name="labels" table="labels">
    <element type="string" column="label"/>
</set>
Defensive patterns

Strategy: try-catch

Validate before calling

// fail fast before transforming: composite-element classes must be loadable
var doc = javax.xml.parsers.DocumentBuilderFactory.newInstance()
        .newDocumentBuilder().parse(hbmFile);
var nodes = doc.getElementsByTagName("composite-element");
for (int i = 0; i < nodes.getLength(); i++) {
    String cls = ((org.w3c.dom.Element) nodes.item(i)).getAttribute("class");
    Class.forName(cls); // throws ClassNotFoundException with the real name
}

Try / catch

try {
    transformer.transform(hbmSource);
} catch (TransformationException e) {
    // message names the collection; cause holds the real failure
    log.error("element-collection transform failed: {} cause={}", e.getMessage(), e.getCause().getMessage());
    throw e;
}

Prevention

When it happens

Trigger: Running hbm.xml->mapping.xml transformation on a <set>/<list>/<bag>/<map>/<array> whose body contains <element> or <composite-element>, where transformElementCollection throws: unresolvable type attribute, a composite-element class missing from the classpath, a bad column/formula definition, or a mismatch with the boot model's property info.

Common situations: Migrating a Hibernate 3/4/5 codebase that mixes hbm.xml with modern bootstrapping; custom UserType/CompositeUserType element types not registered where the transformer runs; typos in the 'type' or 'class' attributes of element/composite-element.

Related errors


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