-
Notifications
You must be signed in to change notification settings - Fork 368
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
674 extract parameters #675
base: master
Are you sure you want to change the base?
Conversation
Thanks, I'll review it when I have some time. |
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.
First of all, thanks, you saved my life!
I've added just one simple but important suggestion from my experience with these wonderful changes.
Also, you should copy these methods to hibernate-60 and hibernate-63 modules too.
I'm looking forward to this PR being merged, and released soon!
Object value = queryParameterBinding.getBindValue(); | ||
parameterValues.add(value); |
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.
Object value = queryParameterBinding.getBindValue(); | |
parameterValues.add(value); | |
if (queryParameterBinding.isMultiValued()) { | |
parameterValues.addAll(queryParameterBinding.getBindValues()); | |
} else { | |
parameterValues.add(queryParameterBinding.getBindValue()); | |
} |
If you call getBindValue
to multi-valued binding, IllegalStateException("Binding is multi-valued; illegal call to #getBindValue") occurs.
Specifically, the extracted SQL of Hibernate 6.0+ using this class contains 'expanded' JdbcParameters. For example, given HQL below:
select team
from Team team
where team.isDeleted = ?1 and team.no in ?2
turns into (abbreviated) SQL as:
select t1_0.no from team t1_0 where t1_0.is_deleted=? and t1_0.no in (?,?,?,?)
when IN clause parameter has 4 items.
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.
Nah, if the IN clause parameter has 3 items (e.g., [1, 2, 3]
) and it's padded to 4 items (e.g., (?,?,?,?)
; by configuring something like hibernate.query.in_clause_parameter_padding
), bindValues
still have 3 items so the size does not match.
I've found the key from the original code! Here is the working code fragment:
JdbcParameterBindings parameterBindings = ReflectionUtils.invokeMethod(
plan,
ReflectionUtils.getMethod(
plan,
"createJdbcParameterBindings",
ReflectionUtils.getClass("org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan$CacheableSqmInterpretation"),
DomainQueryExecutionContext.class
),
cacheableSqmInterpretation,
querySqm
);
return jdbcSelect.getParameterBinders().stream().map(b -> {
JdbcParameterBinding parameterBinding = parameterBindings.getBinding((JdbcParameter) b);
if (parameterBinding != null){
return parameterBinding.getBindValue();
}
return null;
}).toList();
Kotlin version
val parameterBindings = ReflectionUtils.invokeMethod<JdbcParameterBindings>(
plan,
ReflectionUtils.getMethod(
plan,
"createJdbcParameterBindings",
ReflectionUtils.getClass<Any>("org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan\$CacheableSqmInterpretation"),
DomainQueryExecutionContext::class.java,
),
cacheableSqmInterpretation,
querySqm,
)
return jdbcSelect.parameterBinders.map { parameterBindings.getBinding(it as JdbcParameter)?.bindValue }
Copy the getSQLFromSqmQuery
method and replace the code in if (jdbcSelect != null)
block to the fragment.
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.
Nah, if the IN clause parameter has 3 items (e.g.,
[1, 2, 3]
) and it's padded to 4 items (e.g.,(?,?,?,?)
; by configuring something likehibernate.query.in_clause_parameter_padding
),bindValues
still have 3 items so the size does not match.I've found the key from the original code! Here is the working code fragment:
JdbcParameterBindings parameterBindings = ReflectionUtils.invokeMethod( plan, ReflectionUtils.getMethod( plan, "createJdbcParameterBindings", ReflectionUtils.getClass("org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan$CacheableSqmInterpretation"), DomainQueryExecutionContext.class ), cacheableSqmInterpretation, querySqm ); return jdbcSelect.getParameterBinders().stream().map(b -> { JdbcParameterBinding parameterBinding = parameterBindings.getBinding((JdbcParameter) b); if (parameterBinding != null){ return parameterBinding.getBindValue(); } return null; }).toList();Kotlin version
Copy thegetSQLFromSqmQuery
method and replace the code inif (jdbcSelect != null)
block to the fragment.
@KENNYSOFT I'm not working on this ATM, so if you rely on this functionality, I'd suggest you update the PR.
No description provided.