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
JoinedDiscriminatedEntityInitializer handles to-one associations to a JOINED-inheritance hierarchy fetched via join with a discriminator: it holds one concrete initializer per subclass plus a per-subclass 'affectedByFilter' list. When the FK is non-null but no concrete row was found, it decides the row was filtered out if the concrete initializer's flag is set (or, with a null discriminator, assumes filtered when the list is non-empty) and throws EntityFilterException('Entity X with identifier value Y is filtered for association <path>'). The target exists but an enabled @Filter/@SQLRestriction removed its row from the joined result.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/JoinedDiscriminatedEntityInitializer.java:215
data.entityIdentifier = null;
data.concreteInitializer = null;
data.setInstance( null );
final Object foreignKeyValue = keyValueAssembler.assemble( data.getRowProcessingState() );
if ( foreignKeyValue != null ) {
final var concreteInitializer = concreteInitializersByEntityName.get( entityName );
final boolean filteredOut;
if ( concreteInitializer == null ) {
// Discriminator is null, but foreign key is given. Let's just assume this was filtered out,
// if any initializer was affected by a filter
filteredOut = !affectedByFilter.isEmpty();
}
else {
final var index = ArrayHelper.indexOf( concreteInitializers, concreteInitializer );
assert index >= 0;
filteredOut = affectedByFilter.get( index );
}
if ( filteredOut ) {
throw new EntityFilterException( entityName, foreignKeyValue,
fetchedPart.getNavigableRole().getFullPath() );
}
throw new FetchNotFoundException( entityName, foreignKeyValue );
}
}
@Override
public void resolveFromPreviousRow(JoinedDiscriminatedEntityInitializerData data) {
if ( data.getState() == State.UNINITIALIZED ) {
if ( data.getInstance() == null ) {
data.setState( State.MISSING );
}
else {
final var initializer = keyValueAssembler.getInitializer();
if ( initializer != null ) {
initializer.resolveFromPreviousRow( data.getRowProcessingState() );
}
if ( data.concreteInitializer != null ) {View on GitHub (pinned to fad1729dce)
Solutions
- Make the filter condition cover (not exclude) referenced rows, or scope the filter so it is not applied to association targets.
- Mark the association @NotFound(action = NotFoundAction.IGNORE) / optional so a filtered target resolves to null.
- Restructure the filter from the inheritance hierarchy onto the querying entity so subclasses stay fully visible.
- Restore the row so it passes the filter.
Example fix
// before: filter on the inheritance root hides a referenced subclass row
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@FilterDef(name = "tenant", defaultCondition = "tenant_id = :tid")
public class Document { ... }
@ManyToOne(optional = false)
private Document document; // EntityFilterException when the joined row is filtered
// after
@ManyToOne
@NotFound(action = NotFoundAction.IGNORE)
private Document document; Defensive patterns
Strategy: try-catch
Validate before calling
// Before querying with filters on a JOINED hierarchy, check for referenced rows the filter hides
String sql = "select o.id from \"order\" o join document d on d.id = o.doc_id where d.deleted = true";
if (!em.createNativeQuery(sql).getResultList().isEmpty()) {
throw new IllegalStateException("filter hides documents still referenced by orders");
} Try / catch
try {
Order o = em.createQuery("select o from Order o join fetch o.document", Order.class).getSingleResult();
} catch (EntityFilterException e) {
// path names the association; un-filter, restore the row, or map @NotFound(IGNORE)
} Prevention
- Keep inheritance roots unfiltered; apply restrictions at query level instead of @Filter/@SQLRestriction on the hierarchy.
- For associations into hierarchies, prefer @NotFound(action = IGNORE) if rows can be filtered.
- Test each subclass branch as an association target while filters are enabled.
When it happens
Trigger: An association to a JOINED inheritance hierarchy where a filter (@Filter/@SQLRestriction on the base or a subclass) excludes the referenced entity's row, with notFoundAction != IGNORE; discriminator of the subclass row suppressed by the filter's condition.
Common situations: Soft-delete/tenant filters on inheritance roots that hide rows other entities reference; per-subclass restrictions (e.g. @SQLRestriction only on one subclass) that make associations into that subclass fail; filters enabled session-wide leaking into association fetches.
Related errors
- Entity `%s` with identifier value `%s` is filtered for assoc
- Discriminator formulas on joined inheritance hierarchies not
- Entity `%s` with identifier value `%s` is filtered for assoc
- Entity `%s` with identifier value `%s` does not exist
- subclass key mapping has wrong number of columns: " + getEnt
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/c040fe984f9d5023.
Report an issue: GitHub.