hibernate/hibernate-orm · error · MappingException

<many-to-any /> mapping [%s] needs to specify 2 or more colu

Error message

<many-to-any /> mapping [%s] needs to specify 2 or more columns

What it means

<many-to-any/> maps a collection whose elements are polymorphic references chosen by a discriminator. The mapping needs at least two relational values: the first column holds the discriminator value (resolved through meta-type to an entity name) and the remaining column(s) form the foreign key of the referenced entity. If fewer than two column/formula definitions are supplied, the plural-attribute element source rejects the mapping at bootstrap.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/PluralAttributeElementSourceManyToAnyImpl.java:67

					@Override
					public String getSourceName() {
						return null;
					}

					@Override
					public List getColumnOrFormulaElements() {
						return jaxbManyToAnyMapping.getColumn();
					}
				}
		);

		// the list of relational values should contain 2 or more values:
		//		* the first represents the discriminator
		//		* the rest represent the fk

		if ( relationalValueSources.size() < 2 ) {
			throw new MappingException(
					String.format(
							Locale.ENGLISH,
							"<many-to-any /> mapping [%s] needs to specify 2 or more columns",
							pluralAttributeSource.getAttributeRole().getFullPath()
					),
					mappingDocument.getOrigin()
			);
		}

		this.discriminatorSource = new AnyDiscriminatorSource() {
			private final HibernateTypeSource discriminatorTypeSource = new HibernateTypeSourceImpl( jaxbManyToAnyMapping.getMetaType() );
			private final RelationalValueSource discriminatorRelationalValueSource = relationalValueSources.get( 0 );
			private final Map<String,String> discriminatorValueMapping = new HashMap<>();
			{
				for ( JaxbHbmAnyValueMappingType valueMapping : jaxbManyToAnyMapping.getMetaValue() ) {
					discriminatorValueMapping.put(
							valueMapping.getValue(),
							mappingDocument.qualifyClassName( valueMapping.getClazz() )

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add the missing columns: first <column> is the discriminator (its values must map through meta-type to entity names), the remaining <column> elements are the foreign key
  2. Check meta-type and id-type match what the columns actually store, and add <meta-value .../> entries where discriminator values differ from entity names
  3. If the table truly has only one column, <many-to-any> cannot work there - use a plain association or restructure the table first

Example fix

// before
<many-to-any name='items' meta-type='string' id-type='long'>
    <column name='item_id'/>
</many-to-any>

// after - discriminator column added as first column
<many-to-any name='items' meta-type='string' id-type='long'>
    <column name='item_type'/>
    <column name='item_id'/>
</many-to-any>
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: every <many-to-any> must declare >= 2 columns
var m2a = (org.w3c.dom.Element) doc.getElementsByTagName("many-to-any").item(0);
int n = m2a.getElementsByTagName("column").getLength();
if (n < 2)
    throw new IllegalStateException("many-to-any needs discriminator + fk columns, found " + n);

Try / catch

catch (org.hibernate.boot.MappingException e) at Metadata build: the message carries the full attribute role (e.g. Entity.items) - use it to jump straight to the collection element in hbm.xml and add the missing discriminator/fk columns

Prevention

When it happens

Trigger: A <many-to-any meta-type='string' id-type='long'> element inside a collection mapping (<bag>, <set>, <list>, <idbag>, <array> element position) that declares zero or one <column> child, so relationalValueSources.size() < 2 in PluralAttributeElementSourceManyToAnyImpl.

Common situations: Authors used to <many-to-many> or <element> assume one fk column suffices; converting an existing collection to polymorphic without adding a discriminator column to the join table; the table DDL genuinely has only a single fk column and cannot support <many-to-any>.

Related errors


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