{"record":{"id":"c040fe984f9d5023","repo":"hibernate/hibernate-orm","slug":"entity-s-with-identifier-value-s-is-filtered-c040fe","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/JoinedDiscriminatedEntityInitializer.java","lineNumber":215,"sourceCode":"\t\tdata.entityIdentifier = null;\n\t\tdata.concreteInitializer = null;\n\t\tdata.setInstance( null );\n\t\tfinal Object foreignKeyValue = keyValueAssembler.assemble( data.getRowProcessingState() );\n\t\tif ( foreignKeyValue != null ) {\n\t\t\tfinal var concreteInitializer = concreteInitializersByEntityName.get( entityName );\n\t\t\tfinal boolean filteredOut;\n\t\t\tif ( concreteInitializer == null ) {\n\t\t\t\t// Discriminator is null, but foreign key is given. Let's just assume this was filtered out,\n\t\t\t\t// if any initializer was affected by a filter\n\t\t\t\tfilteredOut = !affectedByFilter.isEmpty();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfinal var index = ArrayHelper.indexOf( concreteInitializers, concreteInitializer );\n\t\t\t\tassert index >= 0;\n\t\t\t\tfilteredOut = affectedByFilter.get( index );\n\t\t\t}\n\t\t\tif ( filteredOut ) {\n\t\t\t\tthrow new EntityFilterException( entityName, foreignKeyValue,\n\t\t\t\t\t\tfetchedPart.getNavigableRole().getFullPath() );\n\t\t\t}\n\t\t\tthrow new FetchNotFoundException( entityName, foreignKeyValue );\n\t\t}\n\t}\n\n\t@Override\n\tpublic void resolveFromPreviousRow(JoinedDiscriminatedEntityInitializerData data) {\n\t\tif ( data.getState() == State.UNINITIALIZED ) {\n\t\t\tif ( data.getInstance() == null ) {\n\t\t\t\tdata.setState( State.MISSING );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfinal var initializer = keyValueAssembler.getInitializer();\n\t\t\t\tif ( initializer != null ) {\n\t\t\t\t\tinitializer.resolveFromPreviousRow( data.getRowProcessingState() );\n\t\t\t\t}\n\t\t\t\tif ( data.concreteInitializer != null ) {","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/JoinedDiscriminatedEntityInitializer.java#L197-L233","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: filter on the inheritance root hides a referenced subclass row\n@Entity\n@Inheritance(strategy = InheritanceType.JOINED)\n@FilterDef(name = \"tenant\", defaultCondition = \"tenant_id = :tid\")\npublic class Document { ... }\n\n@ManyToOne(optional = false)\nprivate Document document; // EntityFilterException when the joined row is filtered\n\n// after\n@ManyToOne\n@NotFound(action = NotFoundAction.IGNORE)\nprivate Document document;","handlingStrategy":"try-catch","validationCode":"// Before querying with filters on a JOINED hierarchy, check for referenced rows the filter hides\nString sql = \"select o.id from \\\"order\\\" o join document d on d.id = o.doc_id where d.deleted = true\";\nif (!em.createNativeQuery(sql).getResultList().isEmpty()) {\n    throw new IllegalStateException(\"filter hides documents still referenced by orders\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Order o = em.createQuery(\"select o from Order o join fetch o.document\", Order.class).getSingleResult();\n} catch (EntityFilterException e) {\n    // path names the association; un-filter, restore the row, or map @NotFound(IGNORE)\n}","preventionTips":["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."],"tags":["hibernate","orm","inheritance","joined-inheritance","filter","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"}