Skip to content

Conversation

@TerryTaoYY
Copy link
Contributor

@TerryTaoYY TerryTaoYY commented Jan 4, 2026

Jira: https://hibernate.atlassian.net/browse/HHH-20030

Summary

This PR reduces repeated FilterImpl#validate() work by caching the validated state and only re-validating when filter parameters change.

Motivation

FilterImpl#validate() can be invoked multiple times during query preparation / load flows while enabled filters are consulted. The validation logic iterates defined parameters and checks for an argument or resolver. When filter parameters are unchanged, repeating this validation is redundant.

FilterImpl is also Serializable and its FilterDefinition is restored via afterDeserialize(SessionFactoryImplementor).

Changes

1) Cache validation state with a validated flag

  • Introduce a transient field:
    • private transient boolean validated;
  • Invalidate cached validation whenever parameters are modified:
    • setParameter(..) sets validated = false
    • setParameterList(..) sets validated = false
  • Short-circuit validation only when already validated:
    • validate() returns immediately when validated is true
  • Mark as validated after a successful validation:
    • validated = true at the end of validate()

2) Deserialization restore

  • afterDeserialize(factory) restores the definition via
    SessionFactoryImplementor#getFilterDefinition(..) and re-validates.
  • Unknown filter handling relies on the existing exception behavior of getFilterDefinition(..)
    (redundant null checks / custom exceptions were removed per review feedback).

3) Tests

  • Update/add a serialization regression test (in org.hibernate.internal) to verify the validated
    lifecycle across:
    • Java deserialization (transient flag is not serialized)
    • afterDeserialize(factory)
    • parameter mutations (setParameter / setParameterList)
  • The test no longer asserts a specific pre-restore exception type.

Tests

Executed locally:

./gradlew :hibernate-core:test \
  --tests org.hibernate.internal.FilterImplSerializationTest \
  --tests org.hibernate.orm.test.filter.DynamicFilterTest \
  --tests org.hibernate.orm.test.filter.FilterParameterTests

Behavioral notes / compatibility

  • No public API surface changes.
  • Validation is now cached; resolver lookup via validation becomes less eager once a filter is already validated and unchanged.
  • Validation is still executed on first use, after parameter changes, and after deserialization restore; it is skipped only when already validated and unchanged.
  • Unknown filter handling relies on the existing exception behavior of SessionFactoryImplementor#getFilterDefinition(..) (i.e. UnknownFilterException); this PR removes redundant null checks/custom exceptions.

Checklist

  • Caches validation and invalidates on parameter mutations
  • Covers deserialization/restore via regression test

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.


Copy link
Member

@beikov beikov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than what I mentioned, introducing a dirty flag sound ok to me, though it might be better to flip the flag to validated.

- Track successful FilterImpl#validate() using a transient validated flag so repeated validate() calls are a no-op once validated and unchanged.
- Invalidate cached validation on setParameter(..) / setParameterList(..) and after deserialization restore.
- Rely on SessionFactoryImplementor#getFilterDefinition(..) for unknown-filter failures (remove redundant null checks/exceptions).
- Update the serialization regression test (in org.hibernate.internal) to verify the validated lifecycle across deserialization, afterDeserialize(factory), and parameter mutations.
@TerryTaoYY TerryTaoYY force-pushed the HHH-20030_filterimpl-validate-dirty-cache branch from 3f3191f to d1a7aa9 Compare January 7, 2026 22:25
@TerryTaoYY TerryTaoYY changed the title HHH-20030 - FilterImpl: cache validation and harden deserialization failures HHH-20030 - FilterImpl: cache validation using a validated flag Jan 8, 2026
@beikov beikov merged commit 6502727 into hibernate:main Jan 8, 2026
28 checks passed
@jrenaat
Copy link
Member

jrenaat commented Jan 8, 2026

This has got to be one of the best PR descriptions/motivations I have seen so far. Like, wow. Kudos.

@TerryTaoYY TerryTaoYY deleted the HHH-20030_filterimpl-validate-dirty-cache branch January 9, 2026 02:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants