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

  1. Disable the contributing filter(s) before the delete: session.disableFilter(...)
  2. Incorporate the fragment's condition into the @SQLDelete text itself
  3. Remove entity-level where restrictions (@Where/@WhereRestrict) that apply to deletes when custom SQL is present
  4. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/666c08fd2550aeb3. Report an issue: GitHub.