{"record":{"id":"16032d49c239bd2f","repo":"hibernate/hibernate-orm","slug":"entity-s-with-identifier-value-s-is-filtered","errorCode":null,"errorMessage":"Entity `%s` with identifier value `%s` is filtered for association `%s`","messagePattern":"Entity `(.+?)` with identifier value `(.+?)` is filtered for association `(.+?)`","errorType":"exception","errorClass":"EntityFilterException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityInitializerImpl.java","lineNumber":913,"sourceCode":"\tprotected void setMissing(EntityInitializerData data) {\n\t\tdata.entityKey = null;\n\t\tdata.concreteDescriptor = null;\n\t\tdata.setInstance( null );\n\t\tdata.entityInstanceForNotify = null;\n\t\tdata.entityHolder = null;\n\t\tdata.setState( State.MISSING );\n\n\t\t// super processes the foreign-key target column.  here we\n\t\t// need to also look at the foreign-key value column to check\n\t\t// for a dangling foreign-key\n\n\t\tif ( keyAssembler != null ) {\n\t\t\tfinal Object foreignKeyValue = keyAssembler.assemble( data.getRowProcessingState() );\n\t\t\tif ( foreignKeyValue != null ) {\n\t\t\t\tif ( notFoundAction != NotFoundAction.IGNORE ) {\n\t\t\t\t\tfinal String entityName = getEntityDescriptor().getEntityName();\n\t\t\t\t\tif ( affectedByFilter ) {\n\t\t\t\t\t\tthrow new EntityFilterException( entityName, foreignKeyValue,\n\t\t\t\t\t\t\t\treferencedModelPart.getNavigableRole().getFullPath() );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthrow new FetchNotFoundException( entityName, foreignKeyValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void resolveFromPreviousRow(EntityInitializerData data) {\n\t\tif ( data.getState() == State.UNINITIALIZED ) {\n\t\t\tfinal var entityKey = data.entityKey;\n\t\t\tif ( entityKey == null ) {\n\t\t\t\tsetMissing( data );\n\t\t\t}\n\t\t\telse {","sourceCodeStart":895,"sourceCodeEnd":931,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityInitializerImpl.java#L895-L931","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n@FilterDef(name = \"notDeleted\", defaultCondition = \"deleted = false\")\n@Entity\npublic class Client { ... }\n\n@ManyToOne(optional = false) // boom when the referenced Client is soft-deleted\nprivate Client client;\n\n// after - tolerate filtered targets\n@ManyToOne\n@NotFound(action = NotFoundAction.IGNORE)\nprivate Client client;","handlingStrategy":"try-catch","validationCode":"// Before enabling a filter that hides rows, check what references it would orphan\nString sql = \"select count(*) from invoice i join client c on c.id = i.client_id where c.deleted = true\";\nlong affected = ((Number) em.createNativeQuery(sql).getSingleResult()).longValue();\nif (affected > 0) throw new IllegalStateException(\"Filter would hide \" + affected + \" referenced clients\");","typeGuard":null,"tryCatchPattern":"try {\n    List<Invoice> l = em.createQuery(\"select i from Invoice i\", Invoice.class).getResultList();\n} catch (EntityFilterException e) {\n    // e.getMessage() names entity, id and association path filtered out\n    // options: re-run without the filter, skip, or map @NotFound(IGNORE)\n}","preventionTips":["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."],"tags":["hibernate","orm","filter","soft-delete","entity-filter-exception","association-mapping"],"backgroundTag":"entity-filtered-by-hibernate-filter","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}