hibernate/hibernate-orm · error · UnsupportedOperationException

Not implemented yet

Error message

Not implemented yet

What it means

EntityTableMappingImpl.CompositeKeyMapping.createDomainResult builds a DomainResult for an @EmbeddedId identifier. The source comment states the deliberate limitation: 'this will be challenging if the embeddable defines to-ones. just error for now.' UnsupportedOperationException is therefore thrown whenever a query path needs the composite id as a domain result and the embeddable contains to-one associations.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/EntityTableMappingImpl.java:397

					!sqlSelection.isVirtual()
			);
		}
	}

	public static class CompositeKeyMapping extends AbstractKeyMapping {
		public CompositeKeyMapping(List<KeyColumn> keyColumns, EmbeddableValuedModelPart identifierPart) {
			super( keyColumns, identifierPart );
		}

		@Override
		public <K> DomainResult<K> createDomainResult(
				NavigablePath navigablePath,
				TableReference tableReference,
				String resultVariable,
				DomainResultCreationState creationState) {
			// this will be challenging if the embeddable defines to-ones.
			// just error for now.
			throw new UnsupportedOperationException( "Not implemented yet" );
		}
	}

	public static class KeyColumn extends SelectableMappingImpl implements TableDetails.KeyColumn {

		public KeyColumn(String tableName, SelectableMapping originalMapping) {
			super(
					tableName,
					originalMapping.getSelectionExpression(),
					null, // Leads to construction of a fresh path based on selection expression
					originalMapping.getCustomReadExpression(),
					originalMapping.getCustomWriteExpression(),
					originalMapping.getLength(),
					originalMapping.getPrecision(),
					originalMapping.getScale(),
					originalMapping.getTemporalPrecision(),
					originalMapping.isLob(),
					originalMapping.isNullable(),

View on GitHub (pinned to fad1729dce)

Solutions

  1. Refactor to JPA derived identity: put @ManyToOne + @MapsId on the entity and keep only plain columns in the embeddable - no associations inside @EmbeddedId
  2. Select the id's components individually (root.get("id").get("part")) instead of the composite as a whole
  3. If refactoring is too invasive, load by id (EntityManager.find) instead of projecting the id navigable
  4. Check the Hibernate version's issue tracker for CompositeKeyMapping.createDomainResult support before relying on it

Example fix

// before: association inside @EmbeddedId -> createDomainResult throws
@Embeddable
public class OrderLineId implements Serializable {
    @ManyToOne Order order;   // to-one inside embeddable
    int lineNo;
}

@Entity
public class OrderLine {
    @EmbeddedId OrderLineId id;
}

// after: derived identity with @MapsId
@Embeddable
public class OrderLineId implements Serializable {
    Long orderId;             // plain column
    int lineNo;
}

@Entity
public class OrderLine {
    @EmbeddedId OrderLineId id;
    @ManyToOne(fetch = LAZY)
    @MapsId("orderId")
    Order order;
}
Defensive patterns

Strategy: type-guard

Validate before calling

// reject risky @EmbeddedId shapes at bootstrap, not at query time
static boolean embeddableHasAssociations(Class<?> idClass) {
    for (Field f : idClass.getDeclaredFields()) {
        if (f.isAnnotationPresent(ManyToOne.class) || f.isAnnotationPresent(OneToOne.class)) return true;
    }
    return false;
}

Type guard

static boolean isSafeEmbeddedId(Class<?> idClass) {
    for (Field f : idClass.getDeclaredFields()) {
        if (f.isAnnotationPresent(ManyToOne.class) || f.isAnnotationPresent(OneToOne.class)) {
            return false; // composite-key domain results unsupported for this shape
        }
    }
    return true;
}

Try / catch

try { results = criteriaQuery.select(root.get("id")).getResultList(); } catch (UnsupportedOperationException e) { /* select id components individually instead of the composite */ }

Prevention

When it happens

Trigger: HQL/Criteria selecting the composite id as a whole navigable (e.g. cb.construct(..., root.get("id")), selection of the id path, id()-style references) for an entity whose @EmbeddedId embeddable declares @ManyToOne/@OneToOne fields; native/criteria result construction that materializes the id navigable.

Common situations: The classic JPA pattern of putting @ManyToOne inside the @EmbeddedId (instead of derived identity with @MapsId) and later selecting or projecting the id as a whole; upgrades that route existing queries through this code path.

Related errors


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