-
Notifications
You must be signed in to change notification settings - Fork 616
Spring SPEL expressions in @Query seems to have broken #2125
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
Comments
Hi. It has worked by coincidence, as it serializes the whole Why the whole person? The SpEL expression cannot know if the parameter has been used in another part of the query as well. So we always pass it in as a whole. Here a couple of ways to make this work in SDN 6: import java.util.Optional;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;
public interface PersonRepository extends Neo4jRepository<Person, Long> {
// 1. Use a derived finder method
Optional<Person> findOneByName(String name);
// 2. find by example comes with the repo
// 3. use spel but without passing the whole object
@Query("MATCH (p: Person { name: :#{#name} }) RETURN p")
Optional<Person> get(String name);
// 4. register a custom converter
@Query("MATCH (p: Person { name: :#{#person.name} }) RETURN p")
Optional<Person> get(Person person);
} I work you through: Use a derived finder method for that simple purpose:Probably the easiest one. Method needs to be declared Use findByExampleThat is automatically on the repo, probably the most similar to what you have Simple SpelJust pass the name. Map of known java types works as well. Register a converter for the personpackage com.example.issue0122;
import java.util.Arrays;
import java.util.Map;
import org.neo4j.driver.Value;
import org.neo4j.driver.Values;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.neo4j.core.convert.Neo4jConversions;
@Configuration
public class AdditionalNeo4jConverters {
@Bean
public Neo4jConversions neo4jConversions() {
return new Neo4jConversions(Arrays.asList(new PersonToValueConverter()));
}
static class PersonToValueConverter implements Converter<Person, Value> {
@Override public Value convert(Person source) {
var convertedPerson = Map.of(
"id", source.getId() == null ? -1 : source.getId(),
"name", source.getName()
// plus whatever else, it does not actually be filled, can be empty to
// our spel extracts the value of person.name anyway.
);
return Values.value(convertedPerson);
}
}
} See the parameters passed to the query
it would be same with SDN 5, but without you being in control for that. I hope that helps. |
The argument person to the repository method is just an example for the test case. It could be a filter criteria or some value object etc. In general, one should be able to provide SPEL expressions in query annotations. It used to work before, we have this implemented for over a year and now trying to upgrade to newer versions. JPA based I was under the impression that the Thanks for the examples. |
Spel works the same way before.
Spel extracts the name attribute from the person in your example. And all
other attributes that you refer to in spel.
However, SDN has always passed the complete object as a separate parameter
as well.
Why? Because we can’t pass cypher on the client side and we don’t know if
you used it as cypher parameter as well.
Imagine a scalar string. You might want to use it for dynamic labels and
for a property, the later as a normal cypher parameter (yes, we have seen
this).
So, previous SDN version chose a Jackson generated map for all objects the
bold driver can’t understand natively.
Your best approach is going with the converter I show.
You don’t need to change your Spel for that. And the convert can return the
empty `Value` (Not literal null)
sureshpw <[email protected]> schrieb am Fr. 22. Jan. 2021 um 22:16:
… The argument person to the repository method is just an example for the
test case. It could be a filter criteria or some value object etc. In
general, one should be able to provide SPEL expressions in query
annotations. It used to work before, we have this implemented for over a
year and now trying to upgrade to newer versions.
JPA based @query still works without any problem.
For example: (
https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions
).
I was under the impression that the @query and SPEL expressions are
common for all spring data projects.
Thanks for the examples.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2125 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEAQLYQMRZDEHOOO5BFY6TS3HTMTANCNFSM4WO7YPBQ>
.
|
Registering a custom converter is what I have to do to reduce code changes. Thanks for the explanation. BTW, here is the exact feature request in another spring data project: |
I wonder where my head was last night. We will convert your entities to complete nested maps in 6.1. Regardless of that: Spel works exactly as it did with SDN5 and other modules. The above part is a plus. |
This was working with earlier version of Spring Boot (2.3.4). Giving conversion error in latest version (2.4.2 using SDN 6.0.3). Any suggestions?
The text was updated successfully, but these errors were encountered: