hibernate/hibernate-orm · error · UnsupportedOperationException

Unsupported generated ModelPart: {}

Error message

Unsupported generated ModelPart: {}

What it means

When Hibernate builds the cached JDBC result mapping used to read database-generated values back after insert/update, every generated part must resolve to a basic (single-column) model part (asBasicValuedModelPart() != null). If a generated selectable is a non-basic ModelPart — for example an embeddable attribute whose members are DB-generated — this UnsupportedOperationException is thrown while constructing the mapping producer.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/generator/values/internal/GeneratedValuesHelper.java:232

		final var mappingProducer = new GeneratedValuesMappingProducer();
		for ( int i = 0; i < generatedProperties.size(); i++ ) {
			final var modelPart = generatedProperties.get( i );
			final var basicModelPart = modelPart.asBasicValuedModelPart();
			if ( basicModelPart != null ) {
				mappingProducer.addResultBuilder( new GeneratedValueBasicResultBuilder(
						parentNavigablePath.append( basicModelPart.getSelectableName() ),
						basicModelPart,
						tableGroup,
						// For composite identifiers we may expand generated identifier parts even when
						// supportsArbitraryValues is false; in that case, rely on positional ordering
						// instead of column name resolution.
						supportsArbitraryValues || !basicModelPart.isEntityIdentifierMapping()
								? i
								: null
				) );
			}
			else {
				throw new UnsupportedOperationException( "Unsupported generated ModelPart: " + modelPart.getPartName() );
			}
		}
		return mappingProducer;
	}

	public static BasicValuedModelPart getActualGeneratedModelPart(BasicValuedModelPart modelPart) {
		// Use the root entity descriptor's identifier mapping to get the correct selection
		// expression since we always retrieve generated values for the root table only
		return modelPart.isEntityIdentifierMapping()
				? modelPart.findContainingEntityMapping()
						.getRootEntityDescriptor()
						.getIdentifierMapping()
						.asBasicValuedModelPart()
				: modelPart;
	}

	/**
	 * Returns a list of {@link ModelPart}s that represent the actual generated values

View on GitHub (pinned to fad1729dce)

Solutions

  1. Move database-side generation (@GeneratedColumn, identity) to basic single-column attributes of the entity itself
  2. Use in-memory generation for embeddable members (@Generated or a BeforeExecutionGenerator) so values are written as parameters and no readback is needed
  3. If the embeddable must stay DB-generated, split the generated member out of the embeddable onto the entity
  4. If the mapping looks like it should work, search/raise a Hibernate JIRA — 'Unsupported generated ModelPart' is an internal guard, often a limitation

Example fix

// before — DB-generated member inside a non-id embeddable needs embeddable readback
@Embedded
Audit audit;

@Embeddable class Audit {
    @GeneratedColumn(event = EventType.INSERT)   // embeddable part lands in generated readback
    Instant createdAt;
}

// after — generate in memory; written as a plain parameter
@Embeddable class Audit {
    @Generated(event = EventType.INSERT)
    Instant createdAt;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    sessionFactory = metadata.buildSessionFactory();
}
catch (UnsupportedOperationException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Unsupported generated ModelPart")) {
        throw new IllegalStateException(
                "A non-basic attribute is marked database-generated; move @GeneratedColumn to "
                + "single-column attributes or use @Generated: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Database-side generation attached to a non-identifier embeddable: @GeneratedColumn or identity generation on members of an @Embedded (non-id) attribute, so the generated-properties list contains an EmbeddableValuedModelPart that the result-mapping builder cannot expand (only composite identifiers get expanded).

Common situations: Marking embeddable members as DB-generated on databases whose dialect reads values back via RETURNING; custom generators declaring event types on embeddables; usually reveals a Hibernate limitation rather than a plain configuration mistake.

Related errors


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