hibernate/hibernate-orm · error · UnsupportedOperationException

Only support for basic-valued, entity-valued and embedded mo

Error message

Only support for basic-valued, entity-valued and embedded model-parts have been implemented : " + propertyPath + " [" + subPart + "]

What it means

Hibernate resolves every property path in a @SqlResultSetMapping (@EntityResult + @FieldResult/@ColumnResult) against the domain model when it builds the mapping's fetch mementos. Only three model-part shapes are supported: basic-valued (exactly one column), entity-valued fetchables (FK columns), and embedded attributes (which it recurses into). If the path resolves to anything else - a plural/collection attribute, an @Any mapping, an array - this UnsupportedOperationException is thrown, naming the offending propertyPath and subPart.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDescriptor.java:489

					: parentNavigablePath.append( rootPropertyPathPart );
		}

		@Nonnull
		private FetchMemento getFetchMemento(NavigablePath navigablePath, ModelPart subPart) {
			final var basicPart = subPart.asBasicValuedModelPart();
			if ( basicPart != null ) {
				assert columnNames.size() == 1;
				return new FetchMementoBasicStandard( navigablePath, basicPart, columnNames.get( 0 ) );
			}
			else if ( subPart instanceof EntityValuedFetchable entityValuedFetchable ) {
				return new FetchMementoEntityStandard( navigablePath, entityValuedFetchable, columnNames );
			}
			else if( subPart instanceof EmbeddedAttributeMapping embeddedAttributeMapping ){
				return getFetchMemento( navigablePath,
						embeddedAttributeMapping.findSubPart( unroot( propertyPath ), null ) );
			}
			else {
				throw new UnsupportedOperationException(
						"Only support for basic-valued, entity-valued and embedded model-parts have been implemented : " + propertyPath
						+ " [" + subPart + "]"
				);
			}
		}
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Remove the @FieldResult entry that targets the collection/plural attribute and load collections via a separate query or JOIN FETCH in JPQL
  2. If the attribute is embedded, map the embedding attribute itself and let Hibernate recurse into its sub-parts
  3. For association columns, map them as a separate @EntityResult or as @ColumnResult scalars instead of a field result on a collection
  4. Return scalar columns and use @ConstructorResult with a DTO instead of mapping collections into the entity result

Example fix

// before
@SqlResultSetMapping(
  name = "OrderMapping",
  entities = @EntityResult(
    entityClass = Order.class,
    fields = {
      @FieldResult(name = "id", column = "order_id"),
      @FieldResult(name = "items", column = "item_id") // 'items' is @OneToMany -> unsupported
    }))

// after
@SqlResultSetMapping(
  name = "OrderMapping",
  entities = @EntityResult(
    entityClass = Order.class,
    fields = @FieldResult(name = "id", column = "order_id")))
// fetch items separately: select o from Order o join fetch o.items
Defensive patterns

Strategy: validation

Validate before calling

// Before building the EMF, verify every @FieldResult path targets a supported attribute kind
Metamodel mm = factory.getMetamodel(); // or use reflection over mapping annotations at deploy time
Set<String> plural = ((SingularAttribute) null) == null ? null : null; // sketch:
Set<String> pluralNames = entityManagerFactory.getMetamodel()
    .entity(Order.class).getPluralAttributes().stream()
    .map(Attribute::getName).collect(Collectors.toSet());
for (String path : fieldResultPathsForOrder) {
    if (pluralNames.contains(root(path))) {
        throw new IllegalArgumentException("FieldResult targets plural attribute: " + path);
    }
}

Try / catch

try {
    emf = Persistence.createEntityManagerFactory("pu");
} catch (PersistenceException e) {
    if (e.getCause() instanceof UnsupportedOperationException uoe
            && uoe.getMessage().contains("model-parts")) {
        // log the propertyPath from the message and fix the @SqlResultSetMapping
    }
    throw e;
}

Prevention

When it happens

Trigger: A native SQL query with @SqlResultSetMapping where a @FieldResult points to a @OneToMany/@ManyToMany/@ElementCollection attribute or another non-basic/non-entity/non-embedded model part; also nested paths through a collection. Thrown during bootstrap while Hibernate compiles the named native query mapping.

Common situations: Trying to map joined collection columns into an entity result; porting a JPQL JOIN FETCH query to a native query with field results; upgrading Hibernate versions where mapping resolution got stricter; pointing a field result at an association whose resolved part type is unsupported.

Related errors


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