Skip to content

Issue with JPA Parameter binding after upgrading to spring-data-jpa 2.7.4 #2683

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

Closed
yuvanakannan opened this issue Oct 24, 2022 · 7 comments
Closed
Assignees
Labels
status: duplicate A duplicate of another issue

Comments

@yuvanakannan
Copy link

After Upgrading to spring boot 2.7.5 from 2.7.4, we can see that the NULL query parameters which involves "LIKE" clause are getting bound as empty strings and not as NULL. The same is bound as NULL, if the query condition is "=".

Looks like the problem is due to usage of newer spring-data-jpa version (2.7.5) in spring boot 2.7.5.
Spring boot 2.7.4 was using spring-data-jpa version -2.7.3 where everything looks fine.

For example

If the query is as below and the p_user_name is passed as NULL,
select user from User where :p_user_name is null or userName = :p_user_name

the parameter is properly getting bound as NULL ->
binding parameter [1] as [VARCHAR] - [null]
binding parameter [2] as [VARCHAR] - [null]

Whereas if the query is changed to like below
select user from User where :p_user_name is null or userName LIKE :p_user_name

the parameter is incorrectly getting bound as EMPTY Strings->
binding parameter [1] as [VARCHAR] - []
binding parameter [2] as [VARCHAR] - []

This is failing the existing functionalities in the application.

There seems to be some changes to StringQuery$LikeParameterBinding class (prepare method).
spring-data-jpa.2.7.3 is straight forward:

                @Nullable
		@Override
		public Object prepare(@Nullable Object value) {

			if (value == null) {
				return null;
			}

			switch (type) {
				case STARTING_WITH:
					return String.format("%s%%", value);
				case ENDING_WITH:
					return String.format("%%%s", value);
				case CONTAINING:
					return String.format("%%%s%%", value);
				case LIKE:
				default:
					return value;
			}
		}

from spring-data-jpa-2.7.4 it uses PersistenceProvider.condense method

                @Nullable
		@Override
		public Object prepare(@Nullable Object value) {

			if (value == null) {
				return null;
			}

			switch (type) {
				case STARTING_WITH:
					return String.format("%s%%", PersistenceProvider.condense(value));
				case ENDING_WITH:
					return String.format("%%%s", PersistenceProvider.condense(value));
				case CONTAINING:
					return String.format("%%%s%%", PersistenceProvider.condense(value));
				case LIKE:
				default:
					return PersistenceProvider.condense(value);
			}
		}

This Persistence Provider is returning empty string for some reason when the parameter value is NULL.

public static Object condense(Object value) {

		ClassLoader classLoader = PersistenceProvider.class.getClassLoader();

		if (ClassUtils.isPresent("org.hibernate.jpa.TypedParameterValue", classLoader)) {

			try {

				Class<?> typeParameterValue = ClassUtils.forName("org.hibernate.jpa.TypedParameterValue", classLoader);

				if (typeParameterValue.isInstance(value)) {
					return "";
				}
			} catch (ClassNotFoundException | LinkageError o_O) {
				return value;
			}
		}

		return value;
	}

It might not have been a problem if it is just changing the parameter at the LIKE position, But as the same named parameter is used else where, the parameter value is bound as EMPTY string at all places which is creating the problem.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 24, 2022
@schauder
Copy link
Contributor

Related: #2548

@quaff
Copy link
Contributor

quaff commented Oct 31, 2022

It should fixed by #2655

gregturn added a commit that referenced this issue Nov 7, 2022
gregturn added a commit that referenced this issue Nov 9, 2022
gregturn added a commit that referenced this issue Nov 9, 2022
@gregturn
Copy link
Contributor

gregturn commented Nov 9, 2022

Please check the snapshots to see if this problem is now handled properly.

@steffen-schaefer
Copy link

For our code base I can confirm the affected queries work again with 2.7.6-SNAPSHOT.

Should this also be fixed on recent 3.0.0-SNAPSHOT? On my Jakarta EE based branch with spring-data-jpa 3.0.0-SNAPSHOT I still see a different number of results returned by the affected queries.

@gregturn
Copy link
Contributor

@steffen-schaefer Yes, this was patched on 3.0.0-SNAPSHOT first and then backported. If it's still broken, then it's for a different reason.

@steffen-schaefer
Copy link

@gregturn you are totally right, it's broken for another reason. I submitted #2702

@gregturn
Copy link
Contributor

Duplicates #2655.

@gregturn gregturn added status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 15, 2022
@gregturn gregturn self-assigned this Dec 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

6 participants