hibernate/hibernate-orm · error · EntityFilterException

Entity `%s` with identifier value `%s` is filtered for assoc

Error message

Entity `%s` with identifier value `%s` is filtered for association `%s`

What it means

EntitySelectFetchInitializer resolves to-one associations fetched via a secondary SELECT. Its static checkNotFound() helper is invoked after the select: when the target row was not found, notFoundAction != IGNORE, and the association was affected by an enabled filter (@Filter/@SQLRestriction), it throws EntityFilterException('Entity X with identifier value Y is filtered for association <path>'). The row exists but the filter hid it from the follow-up select, which Hibernate reports as the association being 'filtered'.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntitySelectFetchInitializer.java:302

		if ( lazyInitializer != null ) {
			lazyInitializer.setUnwrap( unwrapProxy );
		}
	}

	void checkNotFound(EntitySelectFetchInitializerData data) {
		checkNotFound( toOneMapping, affectedByFilter,
				concreteDescriptor.getEntityName(),
				data.entityIdentifier );
	}

	static void checkNotFound(
			ToOneAttributeMapping toOneMapping,
			boolean affectedByFilter,
			String entityName, Object identifier) {
		final var notFoundAction = toOneMapping.getNotFoundAction();
		if ( notFoundAction != NotFoundAction.IGNORE ) {
			if ( affectedByFilter ) {
				throw new EntityFilterException( entityName, identifier,
						toOneMapping.getNavigableRole().getFullPath() );
			}
			if ( notFoundAction == NotFoundAction.EXCEPTION ) {
				throw new FetchNotFoundException( entityName, identifier );
			}
		}
	}

	@Override
	public void initializeInstanceFromParent(Object parentInstance, Data data) {
		final var attributeMapping = getInitializedPart().asAttributeMapping();
		final Object instance =
				attributeMapping != null
						? attributeMapping.getValue( parentInstance )
						: parentInstance;
		if ( instance == null ) {
			data.setState( State.MISSING );
			data.entityIdentifier = null;

View on GitHub (pinned to fad1729dce)

Solutions

  1. Adjust the filter definition/parameters so referenced rows remain visible (exclude reference tables from soft-delete/tenant filtering).
  2. Annotate the association @NotFound(action = NotFoundAction.IGNORE) or make it optional so a filtered target yields null instead of an exception.
  3. Prefer joined fetch for associations whose targets may be filtered, and handle absence explicitly in business code.
  4. Restore the row so it satisfies the filter condition.

Example fix

// before
@Entity
@SQLRestriction("archived = false")
public class Product { ... }

@ManyToOne(fetch = FetchType.LAZY) // secondary select hits the restriction
private Product product;

// after
@ManyToOne(fetch = FetchType.LAZY)
@NotFound(action = NotFoundAction.IGNORE) // filtered target -> null instead of throw
private Product product;
Defensive patterns

Strategy: try-catch

Validate before calling

// Before enabling a filter on an association target, count references it would hide
String sql = "select count(*) from cart_item ci join product p on p.id = ci.product_id where p.archived = true";
long hidden = ((Number) em.createNativeQuery(sql).getSingleResult()).longValue();
if (hidden > 0) throw new IllegalStateException("restriction would hide " + hidden + " referenced products");

Try / catch

try {
    Cart c = em.find(Cart.class, id); // lazy select-fetch of filtered products
} catch (EntityFilterException e) {
    // message names the association path; decide: un-filter, ignore (@NotFound(IGNORE)), or skip
}

Prevention

When it happens

Trigger: An association with fetch mode SELECT (e.g. @ManyToOne(fetch=LAZY) resolved later, or proxy initialization selects) where an enabled session filter or @SQLRestriction on the target entity excludes the row with the matching id, combined with a not-ignorable NotFoundAction (default EXCEPTION).

Common situations: Soft-delete or tenant filters applied to reference entities that other entities still reference; filters enabled for a specific report but leaking into association loading within the same session; @SQLRestriction("active = true") on entities used as lookup targets.

Related errors


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