-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Added fallback mechanism for QueryEnhancer
.
#2639
Added fallback mechanism for QueryEnhancer
.
#2639
Conversation
In spring-projects#2564 we discovered that sometimes queries contain content that cannot be parsed by special implementation such as `JSqlParserQueryEnhancer`. Therefore, we implement a fallback mechanism that tries to use the first possible suitable implementation for a given query, that does not fail with an exception on creation. If the first one fails we fallback to the next one until we have reached the `DefaultQueryEnhancer`. Closes spring-projects#2564
@DiegoKrupitza I'm pondering if we need some annotation-drive solution to Choose Your Own QueryEnhancer. Either... public interface PetRepository extends CrudRepository<Pet, Long> {
@Query("....")
@QueryEnhancer(MyOwnQueryEnhancer.class)
public Pet customQuery(String name);
} Either a custom annotation, or an optional attribute added to It would offer people one additional "escape hatch" to tune and adjust things themselves. Otherwise, it seems people run into situations where JSqlParserQueryEnhancer is applied all over the place, but they want to override a single query with an alternative. Or the DefaultQueryEnhancer. |
@gregturn I think your idea is better. By default we use the "best" predefined solution and if devs want to use a special QueryEnhancer for a given Query, the just use the I would design it the following way: public interface PetRepository extends CrudRepository<Pet, Long> {
@Query("....")
@QueryEnhancer(MyOwnQueryEnhancer.class) // custom impl
public Pet customQueryUsesMyOwnQueryEnhancer(String name);
@Query("....")
@QueryEnhancer // using DefaultQueryEnhancer
public Pet customQueryUsesDefaultQueryEnhancer(String name);
@Query("....") // use spring-data-jpa predefined logic for QueryEnhancer
public Pet customQueryUsingOldWayOfDecision(String name);
}
|
I just realised that the Word |
With this commit it is possible to manually select which `@QueryEnhancer` should be used for a given query. Selection can be performed on method or type level. Closes spring-projects#2564
@gregturn I introduced a new annotation for this problem called |
At first glance, this looks quite nice @DiegoKrupitza! I think I'll wait until January to dig in further and try to process it. It does carry some key changes, so I'm not sure we can backport it. |
Yes I agree. It would make sense to include this only in newer versions since there is a fundamental change happening with they "QueryEnhancer". |
@DiegoKrupitza I'm working on merging this PR to |
@DiegoKrupitza I've sifted through all your code, made some tweaks here and there, and done a little polishing. I'm mostly good with it. The one thing I'm uncertain about it, is altering the visibility of a method in |
@DiegoKrupitza I invite you to visit https://github.com/spring-projects/spring-data-jpa/commits/issue/gh-2564, where I've taken all your work, applied tweaks and polishings, added material for the ref docs, and squashed it into a single commit. I'm consulting with my colleagues about the final outcome of |
Resolved via ca6b650. Thanks @DiegoKrupitza! |
After revisiting the entire thread, two things became apparent:
There's conflict potential in the way things are arranged, We should take a step back and revisit the design to not ship something with apparent issues in the design as we cannot make changes once the code has been released in a GA release. |
Thank you for the feedback. I see the problems you are pointing out and yes we should definitely revisit the design. I saw that #2846 introduces a new Parser for JPQL. In my opinion it would make the most sense to wait until this is completed, so we have a "clean canvas" and changes on QueryEnhancer does not the great work of the PR. I cant promise when I find time to spend on redesigning, since I am currently quite busy with my master thesis. But in case someone else wants to work on it in the meantime, I am happy to assist with answering questions etc. |
Thanks for your update. Once the JPQL parser is done, let us know how you want to continue. |
Hello, is there any information when this will be released? |
@daromnik Based upon the recent addition of the query parser, we're not certain what the path forward is at this time. We are waiting @DiegoKrupitza to consult on that direction. |
So I revisited the entire thread again since its been some time when I last worked on this issue. The main goal why we wanted to introduce something like At first sight (and this is what I implemented in the original PR), it would make sense to give the users full control (aka let them select what
So now that we identified that there are (at least 3) problems, what do we do know? I suggest to not move forward with the current design and goal. My proposal is to go into a different direction. Users should not be able to select/provide a custom As @mp911de already proposed, this would mean that // native
@Query(value = "select * from SD_User u where u.emailAddress = ?", nativeQuery = true)
User nativeWillUseWhatIsDefinedByFactory(String emailAddress); // will use what QueryEnhancerFactory#forQuery(...) intended
@Query(value = "select * from SD_User u where u.emailAddress = ?", nativeQuery = true, useDefaultEnhancer=true)
User nativeWillUseDefaultEnhancer(String emailAddress); // will use DefaultQueryEnhancer intended
// JPQL / HQL
@Query(value="....")
User willUseWhatIsDefinedByFactory(String emailAddress); // will use what QueryEnhancerFactory#forQuery(...) intended
@Query(value = "....", useDefaultEnhancer=true)
User willUseDefaultEnhancer(String emailAddress); // will use DefaultQueryEnhancer intended
Why should we follow this proposal? Although we do not satisfy the main goal (mentioned in the first paragraph of this comment), we do allow users to fallback to the "trusted"
I know there might be super rare edge cases where it would be really beneficial to have the possibility to have a custom QueryEnhancer, but this would add a lot of maintenance overhead and complexity to spring jpa that is not desired. Furthermore, as highlighted by @gregturn (here #2564 (comment) ) it is often possible to achieve a goal with way simpler means. |
Thanks @DiegoKrupitza. At this junction, I frankly don't see a huge value in proceeding with this. I'd rather close this issue and let people continue to either:
We are essentially trying to say that Therefore, I don't think |
Yes, I agree with you that this will not add a lot of value to the project, especially when considering that the main goal is to slowly move away from What I would suggest is that we somewhere mention in the documentation, that when someone encounters problems with the query processing that there are 3 possible options one can go for (aka the 3 bullet points you mentioned). |
I'm closing this request with a link to #3005 to track updates to the ref docs about giving readers a jumping off point when queries are too complex for the builtin support. |
In #2564 we discovered that sometimes queries contain content that cannot be parsed by special implementation such as
JSqlParserQueryEnhancer
. Therefore, we implement a fallback mechanism that tries to use the first possible suitable implementation for a given query, that does not fail with an exception on creation. If the first one fails we fallback to the next one until we have reached theDefaultQueryEnhancer
.Closes #2564
NOTE: as mentioned in the comment section of the issue. Members should decide if we should even bother for such special cases that lead to a fail of a special implementation of
QueryEnhancer
.