-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
HHH-19745 Use custom isCompatible and cacheHashCode instead of equals/hashCode for SqmNode #10882
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
Conversation
return e1 == null ? e2 == null : e1.isCompatible( e2 ); | ||
} | ||
|
||
static boolean areCompatible(@Nullable Collection<? extends SqmCacheable> collection1, @Nullable Collection<? extends SqmCacheable> collection2) { |
Check notice
Code scanning / CodeQL
Confusing overloading of methods Note
areCompatible
@@ -25,7 +27,7 @@ | |||
* @author Steve Ebersole | |||
* @author Christian Beikov | |||
*/ | |||
public class SqmCteTable<T> extends AnonymousTupleType<T> implements JpaCteCriteriaType<T> { | |||
public class SqmCteTable<T> extends AnonymousTupleType<T> implements JpaCteCriteriaType<T>, SqmCacheable { |
Check warning
Code scanning / CodeQL
Serializable but no void constructor Warning
AnonymousTupleType
...ore/src/main/java/org/hibernate/query/sqm/tree/expression/ValueBindJpaCriteriaParameter.java
Fixed
Show fixed
Hide fixed
@@ -110,7 +111,7 @@ | |||
return allowJoins; | |||
} | |||
|
|||
public List<SqmJoin<?, ?>> getOrderedJoins() { | |||
public @Nullable List<SqmJoin<?, ?>> getOrderedJoins() { |
Check notice
Code scanning / CodeQL
Exposing internal representation Note
after this call to getOrderedJoins
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be much better to solve this in the opposite way.
That is, I think we should keep using equals()
/ hashCode()
to determine sameness of two ASTs from a "query interpretation" perspective.
And then when we have "special" node types (i.e. parameters) which have some additional different notion of equality, give those node types their own protocol.
Why do I say that? Well:
- it's a change with much smaller impact: instead of changing 152 different node types, we change only those node types with their own special additional notion of equality, and
- we retain the idea that "equality" of two ASTs maps to semantic equivalence of the queries. This is useful and nice!
That is, I see the problem here as arising from the fact that certain special node types (that is, parameters) having their own special use of |
Since the "entry-point" for the compatibility check for those "special node types" is at IMO, identity of the SQM AST nodes is vital to understand if nodes really are the same rather than just equivalent for various cases (parameters, |
WDYM? I don't understand this. Apart from the query interpretation cache, exactly what code is it that is calling |
Most SQM nodes implement
That's the thing, there are uses which we'd need to track down. SQM nodes appear in |
I understand all that. What I'm saying is that parameter node types would have a definition of equals which is consistent with equivalence of the queries (from the point of view of the query interpretation cache, if you want to understand what I mean by "equivalence" here).
I think we should do that work, and track them down.
It's my claim that they should probably not. Or, if they do, we need to understand very carefully why and whether that's correct. What I'm saying is that it's in those cases, the cases where SQM nodes appear in |
Adding to the discussion here, after my work with criteria parameters I did some experiments which confirmed that using identity-based sets and maps where we need to handle them works, even with the value-bind I'm not suggesting the existing solution is better than the one proposed here, I just wanted to confirm that what we have can work, though there might be other bits and pieces that need adjustments like @beikov was saying. |
Awesome, that's great news! |
@mbellade: Sorry for chiming in, but can you also give your solution a try with the following equals/hashCode implementation for value-bind parameters: Objects.equals( getNodeType(), that.getNodeType() );
Objects.hashCode( getNodeType() ); Relying on the value does not make much sense for the query plan cache, because it generates a separate entry for each distinct combination of values. |
Hey @theigl this is a valid improvement proposal, but I would stick with what we know worked before foro now - as you can see, we're still trying to figure out the best approach for criteria query plan caching, and it's very important to get that right, so let's keep the conversation here about that. You're free to open an improvement request on Jira, and perhaps give it a go yourself, we'd be happy to help once we have ironed this out. |
There is https://hibernate.atlassian.net/browse/HHH-19556 created by Gavin, that I somewhat hijacked, but I can create another issue if necessary. My feeling is that only a solution that will eventually work with a type-based equality is a real solution to this issue. Value-based equality is not what users are expecting from the query plan cache and will probably do more harm than good when enabled in a larger application. |
As I've commented elsewhere, I doubt that comparing types is either safe, or necessary. I'm skeptical that two queries can be different if they only differ in the type of a parameter. I mean, that parameter has to be compared or assigned to something, which has to have a matching type. |
@@ -47,7 +47,7 @@ | |||
return null; | |||
} | |||
else { | |||
final Set<SqmParameter<?>> parameters = new HashSet<>( this.parameters.size() ); | |||
final Set<SqmParameter<?>> parameters = new LinkedHashSet<>( this.parameters.size() ); |
Check notice
Code scanning / CodeQL
Possible confusion of local and field Note
copyParameters
parameters
…HashCode instead of equals/hashCode for SqmNode
? one.getPosition().compareTo( o2.getPosition() ) | ||
: 1; | ||
} | ||
throw new HibernateException( "Unexpected SqmParameter type for comparison : " + this + " & " + o2 ); |
Check notice
Code scanning / CodeQL
Use of default toString() Note
Superseded by #10899 |
[Please describe here what your change is about]
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.
https://hibernate.atlassian.net/browse/HHH-19745