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
- Adjust the filter definition/parameters so referenced rows remain visible (exclude reference tables from soft-delete/tenant filtering).
- Annotate the association @NotFound(action = NotFoundAction.IGNORE) or make it optional so a filtered target yields null instead of an exception.
- Prefer joined fetch for associations whose targets may be filtered, and handle absence explicitly in business code.
- 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
- Map associations to filter-restricted entities as @NotFound(action = IGNORE) when absence is expected.
- Enable filters as narrowly as possible (per query/session, not globally).
- Add tests where a filtered target is dereferenced lazily - that is exactly when this throws.
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
- Entity `%s` with identifier value `%s` is filtered for assoc
- Entity `%s` with identifier value `%s` does not exist
- Entity `%s` with identifier value `%s` is filtered for assoc
- Initialization of entity enhancement used to act like a prox
- Property '<propertyName>' may not be annotated '@BatchSize'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/a0a6cc914194afb2.
Report an issue: GitHub.