hibernate/hibernate-orm · error · UnsupportedOperationException

EntityPersister implementation '{className}' does not suppor

Error message

EntityPersister implementation '{className}' does not support 'UniqueKeyLoadable'

What it means

EntityPersister.loadByUniqueKey loads an entity by a unique key instead of its primary key — the path used when a @ManyToOne is resolved against a non-PK unique column (legacy property-ref / referenced-property associations, EntityType.loadByUniqueKey at type/EntityType.java:703). The interface default throws UnsupportedOperationException('EntityPersister implementation ... does not support UniqueKeyLoadable'); AbstractEntityPersister (line 2669) provides the real implementation, so only custom persisters missing the override fail.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java:638

	default Object load(Object id, Object optionalObject, LockOptions lockOptions, SharedSessionContractImplementor session, Boolean readOnly)
			throws HibernateException {
		return load( id, optionalObject, lockOptions, session );
	}

	/**
	 * Performs a load of multiple entities (of this type) by identifier simultaneously.
	 *
	 * @param ids The identifiers to load
	 * @param session The originating Session
	 * @param loadOptions The options for loading
	 *
	 * @return The loaded, matching entities
	 */
	List<?> multiLoad(Object[] ids, SharedSessionContractImplementor session, MultiIdLoadOptions loadOptions);

	@Override
	default Object loadByUniqueKey(String propertyName, Object uniqueKey, SharedSessionContractImplementor session) {
		throw new UnsupportedOperationException(
				"EntityPersister implementation '" + getClass().getName()
						+ "' does not support 'UniqueKeyLoadable'"
		);
	}

	/**
	 * Do a version check (optional operation)
	 */
	void lock(Object id, Object version, Object object, LockMode lockMode, SharedSessionContractImplementor session);

	/**
	 * Do a version check (optional operation)
	 */
	void lock(Object id, Object version, Object object, LockOptions lockOptions, SharedSessionContractImplementor session);

	/**
	 * Persist an instance
	 *

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add a loadByUniqueKey override to the custom persister, following AbstractEntityPersister's implementation
  2. Map the association to the target's primary key instead of the unique column
  3. Drop the custom persister for the target entity

Example fix

// before: association targets a unique (non-PK) column and target uses a custom persister
@ManyToOne
@JoinColumn(name = "sku", referencedColumnName = "sku") // sku is unique, not the PK
private Product product; // Product has custom @Persister -> loadByUniqueKey fails

// after: reference the primary key
@ManyToOne
@JoinColumn(name = "product_id", referencedColumnName = "id")
private Product product;
Defensive patterns

Strategy: type-guard

Type guard

static boolean supportsUniqueKeyLoad(EntityPersister persister) {
    return persister instanceof org.hibernate.persister.entity.AbstractEntityPersister; // implements loadByUniqueKey
}

Try / catch

try {
    return persister.loadByUniqueKey(propertyName, value, session);
}
catch ( UnsupportedOperationException e ) {
    // message names the persister class and 'UniqueKeyLoadable'
    throw new IllegalStateException("Association target cannot be loaded by unique key: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Resolving a to-one association mapped to a unique-key column when the target entity's persister is a custom implementation without a loadByUniqueKey override; direct calls to persister.loadByUniqueKey(...) or EntityUniqueKey-based lookups.

Common situations: Custom persisterClass on the association target; legacy property-ref style associations modernized to annotations but still unique-key based; stub persisters in tests.

Related errors


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