Skip to content

Commit a20e61d

Browse files
authored
Improve error messages for unsupported update assignments (#131)
1 parent 32366d3 commit a20e61d

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

src/integrationTest/java/com/mongodb/hibernate/query/mutation/UpdatingIntegrationTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.mongodb.hibernate.query.mutation;
1818

1919
import com.mongodb.client.MongoCollection;
20+
import com.mongodb.hibernate.internal.FeatureNotSupportedException;
2021
import com.mongodb.hibernate.junit.InjectMongoCollection;
2122
import com.mongodb.hibernate.query.AbstractQueryIntegrationTests;
2223
import com.mongodb.hibernate.query.Book;
@@ -25,6 +26,7 @@
2526
import org.bson.BsonDocument;
2627
import org.hibernate.testing.orm.junit.DomainModel;
2728
import org.junit.jupiter.api.BeforeEach;
29+
import org.junit.jupiter.api.Nested;
2830
import org.junit.jupiter.api.Test;
2931

3032
@DomainModel(annotatedClasses = Book.class)
@@ -228,4 +230,37 @@ void testUpdateWithZeroMutationCount() {
228230
""")),
229231
Set.of(Book.COLLECTION_NAME));
230232
}
233+
234+
@Nested
235+
class Unsupported {
236+
@Test
237+
void testFunctionExpressionAssignment() {
238+
var hql = "update Book b set b.title = upper(b.title) where b.id = 1";
239+
assertMutationQueryFailure(
240+
hql,
241+
query -> {},
242+
FeatureNotSupportedException.class,
243+
"Function expression [upper] as update assignment value for field path [title] is not supported");
244+
}
245+
246+
@Test
247+
void testPredicateExpressionAssignment() {
248+
var hql = "update Book b set b.outOfStock = (b.publishYear > 2000) where b.id = 2";
249+
assertMutationQueryFailure(
250+
hql,
251+
query -> {},
252+
FeatureNotSupportedException.class,
253+
"Predicate expression as update assignment value for field path [outOfStock] is not supported");
254+
}
255+
256+
@Test
257+
void testPathExpressionAssignment() {
258+
var hql = "update Book b set b.publishYear = b.isbn13 where b.id = 3";
259+
assertMutationQueryFailure(
260+
hql,
261+
query -> {},
262+
FeatureNotSupportedException.class,
263+
"Path expression as update assignment value for field path [publishYear] is not supported");
264+
}
265+
}
231266
}

src/main/java/com/mongodb/hibernate/internal/translate/AbstractMqlTranslator.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
102102
import org.hibernate.query.sqm.sql.internal.BasicValuedPathInterpretation;
103103
import org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation;
104+
import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation;
104105
import org.hibernate.query.sqm.tree.expression.Conversion;
105106
import org.hibernate.sql.ast.Clause;
106107
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
@@ -130,6 +131,7 @@
130131
import org.hibernate.sql.ast.tree.expression.Expression;
131132
import org.hibernate.sql.ast.tree.expression.ExtractUnit;
132133
import org.hibernate.sql.ast.tree.expression.Format;
134+
import org.hibernate.sql.ast.tree.expression.FunctionExpression;
133135
import org.hibernate.sql.ast.tree.expression.JdbcLiteral;
134136
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
135137
import org.hibernate.sql.ast.tree.expression.Literal;
@@ -169,6 +171,7 @@
169171
import org.hibernate.sql.ast.tree.predicate.LikePredicate;
170172
import org.hibernate.sql.ast.tree.predicate.NegatedPredicate;
171173
import org.hibernate.sql.ast.tree.predicate.NullnessPredicate;
174+
import org.hibernate.sql.ast.tree.predicate.Predicate;
172175
import org.hibernate.sql.ast.tree.predicate.SelfRenderingPredicate;
173176
import org.hibernate.sql.ast.tree.predicate.ThruthnessPredicate;
174177
import org.hibernate.sql.ast.tree.select.QueryGroup;
@@ -694,7 +697,8 @@ public void visitUpdateStatement(UpdateStatement updateStatement) {
694697
var fieldPath = acceptAndYield(fieldReferences.get(0), FIELD_PATH);
695698
var assignedValue = assignment.getAssignedValue();
696699
if (!isValueExpression(assignedValue)) {
697-
throw new FeatureNotSupportedException();
700+
throw new FeatureNotSupportedException(
701+
getUnsupportedUpdateValueAssignmentMessage(fieldPath, assignedValue));
698702
}
699703
var fieldValue = acceptAndYield(assignedValue, VALUE);
700704
fieldUpdates.add(new AstFieldUpdate(fieldPath, fieldValue));
@@ -1205,4 +1209,19 @@ public void appendSql(String fragment) {
12051209
throw new FeatureNotSupportedException();
12061210
}
12071211
}
1212+
1213+
private static String getUnsupportedUpdateValueAssignmentMessage(final String fieldPath, Expression assignedValue) {
1214+
if (assignedValue instanceof FunctionExpression ex) {
1215+
return "Function expression [%s] as update assignment value for field path [%s] is not supported"
1216+
.formatted(ex.getFunctionName(), fieldPath);
1217+
} else if (assignedValue instanceof Predicate) {
1218+
return "Predicate expression as update assignment value for field path [%s] is not supported"
1219+
.formatted(fieldPath);
1220+
} else if (assignedValue instanceof SqmPathInterpretation) {
1221+
return "Path expression as update assignment value for field path [%s] is not supported"
1222+
.formatted(fieldPath);
1223+
} else {
1224+
return "Update assignment value for field path [%s] is not supported".formatted(fieldPath);
1225+
}
1226+
}
12081227
}

0 commit comments

Comments
 (0)