-
Notifications
You must be signed in to change notification settings - Fork 38.4k
spring-r2dbc can't correctly fill multiple named parameters with list #34768
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
Comments
Possible fix below, sorry my network speed to download gradle and dependencies is too slow, I haven't tested it. $ git diff -w
diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java index f6696e8d9c..91ae7b35a4 100644
--- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java
+++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java
@@ -529,6 +529,7 @@ abstract class NamedParameterUtils {
if (parameter.getValue() instanceof Collection collection) {
Iterator<Object> iterator = collection.iterator();
Iterator<BindMarker> markers = bindMarkers.iterator();
+ do {
while (iterator.hasNext()) {
Object valueToBind = iterator.next();
if (valueToBind instanceof Object[] objects) {
@@ -540,6 +541,13 @@ abstract class NamedParameterUtils {
bind(target, markers, valueToBind);
}
}
+
+ if (markers.hasNext()) {
+ iterator = collection.iterator();
+ } else {
+ break;
+ }
+ } while (true);
}
else {
for (BindMarker bindMarker : bindMarkers) {
|
Fixes spring-projects#34768 Signed-off-by: Yubao Liu <[email protected]>
Hi @Dieken, Congratulations on submitting your first issue for the Spring Framework! 👍 Before I noticed that you had submitted PR #34769, I put together some tests in an attempt to reproduce the behavior you described, and I pushed those in commit 018d3c9. Those tests pass. For example, the
That is expanded from the following SQL. SELECT * FROM legoset WHERE version IN (:numbers) OR manual IN (:numbers) Thus, I was not able to reproduce your claim. If you would like us to investigate this further (or to consider your PR), please provide tests that fail before the proposed change and then pass after the proposed change. Thanks, Sam |
No idea why your tests can pass, I can reproduce the issue with test code below: demo/src/test/java/com/example/demo/DemoApplicationTests.java: package com.example.demo;
import java.util.List;
import lombok.Data;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.r2dbc.core.DatabaseClient;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private DatabaseClient db;
@BeforeEach
void setupDb() {
db.sql("CREATE TABLE IF NOT EXISTS fund_info (id int not null primary key, fund_code varchar(20) not null)")
.then()
.block();
}
@Test
void contextLoads() {
}
@Test
void testIt() {
Req r = new Req();
r.fundCodes = List.of("000001");
db.sql("SELECT * FROM fund_info WHERE fund_code IN (:fundCodes) OR fund_code IN (:fundCodes)")
//.bind("fundCodes", r.fundCodes)
.bindProperties(r)
.fetch()
.all()
.collectList()
.block();
}
@Data
static class Req {
private List<String> fundCodes;
}
} |
demo/src/main/resources/application.properties:
|
Seems there are multiple bugs: (UPDATED: the Lombok bug is caused by JDK 23, it works with JDK 21, so just ignore this case) H21. With Lombok and bindProperties: FAIL
Throws exception:
2. With plain JavaBean and bindProperties: PASS
3. bind("fundCodes", r.fundCodes): PASSMySQL1. With Lombok and bindProperties: FAIL
2. With plain JavaBean and bindProperties: FAIL
3. bind("fundCodes", r.fundCodes): FAIL
|
https://github.com/spring-projects/spring-framework/blob/v7.0.0-M3/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java#L528
For example, for
SELECT ... WHERE fund_codeA in (:fundCodes) OR fund_codeB in (:fundCodes)
,fundCodes
references a List, then the code above only fill the first occurrence of:fundCodes
.The text was updated successfully, but these errors were encountered: