Skip to content

Specification.not() fails with NullPointerException when other Specification returns null #3849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
SWQXDBA opened this issue Apr 21, 2025 · 3 comments · May be fixed by #3856
Open

Specification.not() fails with NullPointerException when other Specification returns null #3849

SWQXDBA opened this issue Apr 21, 2025 · 3 comments · May be fixed by #3856
Assignees
Labels
status: ideal-for-contribution An issue that a contributor can help us with type: bug A general bug

Comments

@SWQXDBA
Copy link

SWQXDBA commented Apr 21, 2025

/**
	 * Negates the given {@link Specification}.
	 *
	 * @param <T> the type of the {@link Root} the resulting {@literal Specification} operates on.
	 * @param spec can be {@literal null}.
	 * @return guaranteed to be not {@literal null}.
	 * @since 2.0
	 */
	static <T> Specification<T> not(@Nullable Specification<T> spec) {

		return spec == null //
				? (root, query, builder) -> null //
				: (root, query, builder) -> builder.not(spec.toPredicate(root, query, builder));
	}

Cannot invoke "org.hibernate.query.sqm.tree.expression.SqmExpression.getExpressible()" because "booleanExpression" is null\njava.lang.NullPointerException: Cannot invoke "org.hibernate.query.sqm.tree.expression.SqmExpression.getExpressible()" because "booleanExpression" is null
at org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate.(SqmBooleanExpressionPredicate.java:38)
at org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate.(SqmBooleanExpressionPredicate.java:31)
at org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.wrap(SqmCriteriaNodeBuilder.java:497)
at org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.not(SqmCriteriaNodeBuilder.java:2088)
at org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.not(SqmCriteriaNodeBuilder.java:192)
at org.springframework.data.jpa.domain.Specification.lambda$1(Specification.java:58)
at org.springframework.data.jpa.domain.SpecificationComposition.toPredicate(SpecificationComposition.java:62)
at org.springframework.data.jpa.domain.SpecificationComposition.lambda$0(SpecificationComposition.java:49)
at org.springframework.data.jpa.domain.SpecificationComposition.toPredicate(SpecificationComposition.java:62)

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 21, 2025
@SWQXDBA
Copy link
Author

SWQXDBA commented Apr 21, 2025

In the current semantics, if specification.toPredicate() returns null, it means no condition—which logically translates to an Expression true.

Thus, in the not() method, we can return criteriaBuilder.disjunction() to represent false, because:
not(true) → false

This ensures that negating a null predicate (implicitly true) correctly results in false instead of throwing an NPE.

@mp911de mp911de self-assigned this Apr 22, 2025
@mp911de
Copy link
Member

mp911de commented Apr 22, 2025

Care to submit a pull request?

@mp911de mp911de added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Apr 22, 2025
@mp911de mp911de changed the title The Specification.not() method does not handle the case where the predicate is null, resulting in an NPE (NullPointerException). Specification.not() fails with NullPointerException when other Specification returns null Apr 22, 2025
@mp911de mp911de added the status: ideal-for-contribution An issue that a contributor can help us with label Apr 22, 2025
@SWQXDBA
Copy link
Author

SWQXDBA commented Apr 23, 2025

Care to submit a pull request?

I'll try to submit a PR over the weekend

SWQXDBA added a commit to SWQXDBA/spring-data-jpa that referenced this issue Apr 23, 2025
When toPredicate() returns null, Specification.not() now returns
builder.disjunction() instead of builder.not(null). This change
ensures proper handling of null predicates in negated specifications.

spring-projects#3849
SWQXDBA added a commit to SWQXDBA/spring-data-jpa that referenced this issue Apr 23, 2025
spring-projects#3849

When toPredicate() returns null, Specification.not() now returns
builder.disjunction() instead of builder.not(null). This change
ensures proper handling of null predicates in negated specifications.
SWQXDBA added a commit to SWQXDBA/spring-data-jpa that referenced this issue Apr 23, 2025
spring-projects#3849

When toPredicate() returns null, Specification.not() now returns
builder.disjunction() instead of builder.not(null). This change
ensures proper handling of null predicates in negated specifications.

Signed-off-by: SWQXDBA <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: ideal-for-contribution An issue that a contributor can help us with type: bug A general bug
Projects
None yet
3 participants