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
While initializing a joined to-one fetch, EntityInitializerImpl.setMissing() detects a non-null FK value but no target row. It then distinguishes two causes: if the association was affected by an enabled filter (@Filter on the target entity/association, or @SQLRestriction) and notFoundAction != IGNORE, it throws EntityFilterException('Entity X with identifier value Y is filtered for association <path>'). The target row exists in the database but the active filter definition excludes it from the join, turning a valid reference into an apparent dangling FK from Hibernate's point of view.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityInitializerImpl.java:913
protected void setMissing(EntityInitializerData data) {
data.entityKey = null;
data.concreteDescriptor = null;
data.setInstance( null );
data.entityInstanceForNotify = null;
data.entityHolder = null;
data.setState( State.MISSING );
// super processes the foreign-key target column. here we
// need to also look at the foreign-key value column to check
// for a dangling foreign-key
if ( keyAssembler != null ) {
final Object foreignKeyValue = keyAssembler.assemble( data.getRowProcessingState() );
if ( foreignKeyValue != null ) {
if ( notFoundAction != NotFoundAction.IGNORE ) {
final String entityName = getEntityDescriptor().getEntityName();
if ( affectedByFilter ) {
throw new EntityFilterException( entityName, foreignKeyValue,
referencedModelPart.getNavigableRole().getFullPath() );
}
else {
throw new FetchNotFoundException( entityName, foreignKeyValue );
}
}
}
}
}
@Override
public void resolveFromPreviousRow(EntityInitializerData data) {
if ( data.getState() == State.UNINITIALIZED ) {
final var entityKey = data.entityKey;
if ( entityKey == null ) {
setMissing( data );
}
else {View on GitHub (pinned to fad1729dce)
Solutions
- Widen the filter condition or its parameters so referenced rows are not excluded (e.g. exempt reference tables from the tenant/soft-delete filter).
- If a filtered-out target should read as null, annotate the association @NotFound(action = NotFoundAction.IGNORE) (or make it optional) so Hibernate nulls it instead of throwing.
- Do not apply @Filter/@SQLRestriction to entities used as mandatory association targets - filter only the querying side.
- Un-soft-delete or restore the row so it passes the filter.
Example fix
// before
@FilterDef(name = "notDeleted", defaultCondition = "deleted = false")
@Entity
public class Client { ... }
@ManyToOne(optional = false) // boom when the referenced Client is soft-deleted
private Client client;
// after - tolerate filtered targets
@ManyToOne
@NotFound(action = NotFoundAction.IGNORE)
private Client client; Defensive patterns
Strategy: try-catch
Validate before calling
// Before enabling a filter that hides rows, check what references it would orphan
String sql = "select count(*) from invoice i join client c on c.id = i.client_id where c.deleted = true";
long affected = ((Number) em.createNativeQuery(sql).getSingleResult()).longValue();
if (affected > 0) throw new IllegalStateException("Filter would hide " + affected + " referenced clients"); Try / catch
try {
List<Invoice> l = em.createQuery("select i from Invoice i", Invoice.class).getResultList();
} catch (EntityFilterException e) {
// e.getMessage() names entity, id and association path filtered out
// options: re-run without the filter, skip, or map @NotFound(IGNORE)
} Prevention
- Do not apply @Filter/@SQLRestriction to entities used as association targets.
- Document for each filter which entities it touches; review when adding associations.
- Map associations to filterable targets as @NotFound(action = IGNORE) or optional when absence is expected.
- Test with filter enabled plus soft-deleted reference data present.
When it happens
Trigger: session.enableFilter(...) (or @SQLRestriction on the target entity) whose condition excludes the referenced row, combined with an association mapped with a not-ignorable NotFoundAction (EXCEPTION is the default); loading an entity whose @ManyToOne target is filtered out by tenant/active/soft-delete filters.
Common situations: Soft-delete filters (@Filter(condition="deleted = false")) that hide rows still referenced by other tables; multi-tenant filters whose parameters exclude rows another tenant references; enabling a filter for one use case and forgetting it also hides reference data used everywhere.
Related errors
- Entity `%s` with identifier value `%s` is filtered for assoc
- Entity `%s` with identifier value `%s` is filtered for assoc
- Invalid attempt to apply where-restriction on top of custom
- Invalid attempt to apply where-filter on top of custom sql-d
- Named query definition is null
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/16032d49c239bd2f.
Report an issue: GitHub.