-
Notifications
You must be signed in to change notification settings - Fork 198
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
Fix binding embeded id parameter #3131
Conversation
@@ -48,6 +51,13 @@ public QueryParameterBinding bind(BindingContext bindingContext) { | |||
if (outgoingQueryParameterProperty == null) { | |||
return new SimpleParameterBinding(name, DataType.forType(paramClass), bindingContext.isExpandable(), value); | |||
} | |||
return new PropertyPathParameterBinding(name, outgoingQueryParameterProperty, bindingContext.isExpandable(), value); | |||
Object parameterValue = value; | |||
if (value != null && outgoingQueryParameterProperty.getProperty().getOwner().isEmbeddable()) { |
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.
@dstepanov So here is the case that DefaultParameterExpression
gets value as embeded id but binding parameters should be each field of embedded id. So, we need to extract value for the param if field belongs to embedded id and passed value is embedded id. Not sure if this is safe enough and if there is some better approach to extract correct value for embedded id part(s).
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 should be expanded in the equals operator, similar to the composite identity:
Lines 2019 to 2032 in 74fbe2a
public void visitEquals(Expression<?> leftExpression, Expression<?> rightExpression, boolean ignoreCase) { | |
if (leftExpression instanceof io.micronaut.data.model.jpa.criteria.PersistentPropertyPath<?> persistentPropertyPath) { | |
PersistentPropertyPath propertyPath = persistentPropertyPath.getPropertyPath(); | |
PersistentProperty property = propertyPath.getProperty(); | |
if (computePropertyPaths() && property instanceof Association) { | |
List<IPredicate> predicates = new ArrayList<>(); | |
PersistentEntityUtils.traverse(propertyPath, pp -> | |
predicates.add(new BinaryPredicate( | |
new DefaultPersistentPropertyPath<>(pp, null), | |
rightExpression, | |
ignoreCase ? PredicateBinaryOp.EQUALS_IGNORE_CASE : PredicateBinaryOp.EQUALS | |
)) | |
); | |
if (predicates.size() == 1) { |
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.
Predicate and criteria is ok, association is expanded and query generated is
UPDATE `Shipment1` SET `field`=? WHERE (`sp_country` = ? AND `sp_city` = ?)
but each of these 2 bindings for WHERE criteria is ShipmentId
instead of each property of the embedded id getting from here
@NotNull
@NextMajorVersion("Require non null y")
private Predicate predicate(Expression<?> x, Object y, PredicateBinaryOp op) {
if (x instanceof IdExpression) {
return new ExpressionBinaryPredicate(x, literal(y), op);
}
return new PersistentPropertyBinaryPredicate<>(requireProperty(x), literal(y), op);
}
This is why we need to get actual embedded id field value in the bind
method above.
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.
That should be done a bit differently:
- We need to add
PersistentPropertyPath parameterPropertyPath
toDefaultParameterExpression
like it's inSourceParameterExpressionImpl
- When the property is expanded, we should try to recognize
DefaultParameterExpression
and clone it to a new parameter withparameterPropertyPath
set the left property path DefaultParameterExpression
should use the same logic as in the source one to calculateparameterBindingPath
DefaultBindableParametersStoredQuery
should support usinggetParameterBindingPath
for cases when the value set
Quality Gate passedIssues Measures |
Fix for issue #3125