hibernate/hibernate-orm · error · HibernateException
Invalid attempt to apply where-filter on top of custom sql-d
Error message
Invalid attempt to apply where-filter on top of custom sql-delete mapping :
What it means
Companion guard to setWhere: TableDeleteBuilderStandard.addWhereFragment appends additional where fragments to a generated delete. When the mutation is backed by custom SQL (@SQLDelete) and a non-null fragment is added, it throws HibernateException('Invalid attempt to apply where-filter on top of custom sql-delete mapping') - a custom-SQL delete cannot be extended with dynamically generated fragments.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/TableDeleteBuilderStandard.java:100
public String getWhereFragment() {
return whereFragment;
}
@Override
public void setWhere(String fragment) {
if ( mutationDetails.getCustomSql() != null && fragment != null ) {
throw new HibernateException(
"Invalid attempt to apply where-restriction on top of custom sql-delete mapping : " +
getMutationTarget().getNavigableRole().getFullPath()
);
}
}
@Override
public void addWhereFragment(String fragment) {
if ( mutationDetails.getCustomSql() != null && fragment != null ) {
throw new HibernateException(
"Invalid attempt to apply where-filter on top of custom sql-delete mapping : " +
getMutationTarget().getNavigableRole().getFullPath()
);
}
}
@Override
public TableDelete buildMutation() {
if ( mutationDetails.getCustomSql() != null ) {
return new TableDeleteCustomSql(
getMutatingTable(),
mutationDetails,
getMutationTarget(),
sqlComment,
getKeyRestrictionBindings(),
getOptimisticLockBindings(),
getParameters()
);View on GitHub (pinned to fad1729dce)
Solutions
- Disable the contributing filter(s) before the delete: session.disableFilter(...)
- Incorporate the fragment's condition into the @SQLDelete text itself
- Remove entity-level where restrictions (@Where/@WhereRestrict) that apply to deletes when custom SQL is present
- Use a direct bulk delete (JPQL/native) for these entities
Example fix
// before session.enableFilter( "tenant" ); session.remove( employee ); // @SQLDelete + filter fragment -> addWhereFragment throws // after session.disableFilter( "tenant" ); session.remove( employee );
Defensive patterns
Strategy: validation
Validate before calling
// before deleting a soft-delete entity, drop any filters that target it session.getEnabledFilterNames().forEach( session::disableFilter ); session.remove( entity );
Prevention
- Disable contributing filters before deletes on @SQLDelete-mapped entities
- Include filter conditions in the custom SQL text itself
- Route such deletes through bulk statements that bypass the delete builder
When it happens
Trigger: Deleting an entity with custom SQL delete while fragments get appended - enabled session filters contributing delete restrictions, @WhereRestrict-style dynamic restrictions, or versioned/conditional delete handling that adds fragments at build time.
Common situations: Soft-delete entities combined with enabled filters during delete; frameworks that auto-enable filters per request and then delete; filters added late in a session's lifecycle after entities were loaded.
Related errors
- Invalid attempt to apply where-restriction on top of custom
- write expression must contain exactly one value placeholder
- Entity may not be null
- Couldn't find table reference
- Unable to locate parameter `%s.%s` for %s - %s : %s
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/666c08fd2550aeb3.
Report an issue: GitHub.