Skip to content
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

SpEL template behavior is inconsistent [DATAJPA-1266] #1597

Closed
spring-projects-issues opened this issue Feb 15, 2018 · 4 comments
Closed

SpEL template behavior is inconsistent [DATAJPA-1266] #1597

spring-projects-issues opened this issue Feb 15, 2018 · 4 comments
Assignees
Labels
in: query-parser Everything related to parsing JPQL or SQL type: bug A general bug

Comments

@spring-projects-issues
Copy link

Jens Schauder opened DATAJPA-1266 and commented

The following tests succeed when added to ExpressionBasedStringQueryUnitTests

	@Test
	public void doesTemplatingWhenEntityNameSpelIsPresent() {

		StringQuery query = new ExpressionBasedStringQuery("select #{#entityName + 'Hallo'} from #{#entityName} u", metadata, SPEL_PARSER);

		assertThat(query.getQueryString(), is("select UserHallo from User u"));
	}

	@Test
	public void doesNotTemplatingWhenEntityNameSpelIsNotPresent() {

		StringQuery query = new ExpressionBasedStringQuery("select #{#entityName + 'Hallo'} from User u", metadata, SPEL_PARSER);

		assertThat(query.getQueryString(), is("select #{#entityName + 'Hallo'} from User u"));
	}

	@Test
	public void doesTemplatingWhenEntityNameSpelIsPresentForBindParameter() {

		StringQuery query = new ExpressionBasedStringQuery("select u from #{#entityName} u where name = :#{#something}", metadata, SPEL_PARSER);

		assertThat(query.getQueryString(), is("select u from User u where name = :"));
	}

We only apply templating if #\{#entityName\} is present in the query string. If we do so, we use the full-blown SpEL templating mechanism, i.e also other SpEL expressions get evaluated and replaced.

Also, SpEL expressions for bind parameters only get protected from this when they start with ?# not when they start with :#


No further details from DATAJPA-1266

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

I guess we need to:

  1. Replace bind variables using the API to be created, so that an intermediate query string can be produced with the SpEL-based bind variables replaced by synthetic placeholders and the expressions externalized for standalone evaluation.
  2. Replace all remaining SpEL expressions evaluated eagerly.

If we can trigger 2 without masking the SpEL-based bind variables to be handled in 1, we can also flip the steps, should that make things easier

@spring-projects-issues spring-projects-issues added the type: bug A general bug label Dec 30, 2020
@spring-projects-issues spring-projects-issues added the in: query-parser Everything related to parsing JPQL or SQL label Dec 30, 2020
@gregturn
Copy link
Contributor

gregturn commented Mar 22, 2023

I have re-input @schauder 's original test cases and run them through the latest-and-greatest of Spring Data JPA, parser and all. Can either @schauder or @odrotbohm verify that this is the desired final results? If so, I'll add these test cases and push to main.

@Test
public void doesTemplatingWhenEntityNameSpelIsPresent() {

	StringQuery query = new ExpressionBasedStringQuery("select #{#entityName + 'Hallo'} from #{#entityName} u",
			metadata, SPEL_PARSER, false);

	assertThat(query.getQueryString()).isEqualTo("select UserHallo from User u");
}

@Test
public void doesNoTemplatingWhenEntityNameSpelIsNotPresent() {

	StringQuery query = new ExpressionBasedStringQuery("select #{#entityName + 'Hallo'} from User u", metadata,
			SPEL_PARSER, false);

	assertThat(query.getQueryString()).isEqualTo("select #{#entityName + 'Hallo'} from User u");
}

@Test
public void doesTemplatingWhenEntityNameSpelIsPresentForBindParameter() {

	StringQuery query = new ExpressionBasedStringQuery("select u from #{#entityName} u where name = :#{#something}",
			metadata, SPEL_PARSER, false);

	assertThat(query.getQueryString()).isEqualTo("select u from User u where name = :__$synthetic$__1");
}

@schauder
Copy link
Contributor

I think the second should be select UserHallo from User u

gregturn added a commit that referenced this issue Jul 26, 2023
@gregturn gregturn self-assigned this Jul 26, 2023
gregturn added a commit that referenced this issue Jul 26, 2023
@gregturn
Copy link
Contributor

Merged to main. Backported to 3.1.x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: query-parser Everything related to parsing JPQL or SQL type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants