You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using Vavr object like an Option as an argument with SqlObjects like
@SqlQuery("select * from something where :name is null or name = :name order by id")
@RegisterBeanMapper(Something.class)
List<Something> selectByOptionName(@BindOption<String> name);
does not work.
Based on the TestVavrValueArgumentFactoryWithDB in JDBI Vavr module, I created these test cases for using an Option as an argument.
publicclassTestVavrValueArgumentFactoryWithDBSqlObjects {
privatestaticfinalSomethingERICSOMETHING = newSomething(1, "eric");
privatestaticfinalSomethingBRIANSOMETHING = newSomething(2, "brian");
@RegisterExtensionpublicJdbiExtensionh2Extension = JdbiExtension.h2().withInitializer(TestingInitializers.something()).installPlugins();
@BeforeEachpublicvoidcreateTestData() {
Handlehandle = h2Extension.getSharedHandle();
handle.createUpdate("insert into something (id, name) values (1, 'eric')").execute();
handle.createUpdate("insert into something (id, name) values (2, 'brian')").execute();
}
@TestpublicvoidtestGetOptionShouldReturnCorrectRowUsingExtension() {
List<Something> result = h2Extension.getJdbi()
.withExtension(Dao.class, dao -> dao.selectByOptionName(Option.of("eric")));
assertThat(result).hasSize(1);
}
@TestpublicvoidtestGetOptionEmptyShouldReturnAllRowsUsingExtension() {
List<Something> result = h2Extension.getJdbi()
.withExtension(Dao.class, dao -> dao.selectByOptionName(Option.none()));
assertThat(result).hasSize(2);
}
interfaceDao {
@SqlQuery("select * from something where :name is null or name = :name order by id")
@RegisterBeanMapper(Something.class)
List<Something> selectByOptionName(@BindOption<String> name);
}
With a Some the query works, but with a None it does not.
This is somewhat different than what we see in our codebase. Then the test with a Some value also fails with
org.jdbi.v3.core.statement.UnableToExecuteStatementException: org.postgresql.util.PSQLException: ERROR: operator does not exist: integer = bigint[]
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
Position: 50 [statement:"SELECT * FROM our_table WHERE id = :id ", arguments:{positional:{0:Some(47)}, named:{id:Some(47)}, finder:[]}]
While debugging I notice that the VavrValueArgumentFactory.build method does not get called when using SqlObject.
It does get called when using the Java Api .bind("name", Option.none()).
The text was updated successfully, but these errors were encountered:
The problem is that Option implements Iterable and when creating the arugment, the SqlArrayArgumentFactory "snatches" the argument because it deals with all iterable arguments. This is a shortcoming in factory selection. I'll figure something out.
Turns out, this has never worked before. To work with SqlObjects,
the argument factory needs to implement ArgumentFactory.Preparable,
otherwise another factory (in this case one that accepts anything
iterable) would take precedence.
Rewrite the factory to support Preparable, add unit tests suggested
by @diversit.
Fixesjdbi#2529
Using Vavr object like an
Option
as an argument with SqlObjects likedoes not work.
Based on the
TestVavrValueArgumentFactoryWithDB
in JDBI Vavr module, I created these test cases for using an Option as an argument.With a
Some
the query works, but with aNone
it does not.This is somewhat different than what we see in our codebase. Then the test with a
Some
value also fails withWhile debugging I notice that the
VavrValueArgumentFactory.build
method does not get called when using SqlObject.It does get called when using the Java Api
.bind("name", Option.none())
.The text was updated successfully, but these errors were encountered: