JDBI - Bind Bean with List properties

1.5k views Asked by At

I have a program using JDBI to query a Redshift cluster, and I'm struggling to generate the appropriate SQL statement using the bindBean functionality.

@Data @Builder
public static class User {
    private String id;
    private List<String> emailAddresses;
}

private Jdbi createJdbi(
        @NonNull String jdbcUri,
        @NonNull String username,
        @NonNull String password) {
    RedshiftSimpleDataSource redshiftDataSource = new RedshiftSimpleDataSource();
    redshiftDataSource.setUrl(jdbcUri);
    redshiftDataSource.setUser(username);
    redshiftDataSource.setPassword(password);
    return Jdbi.create(redshiftDataSource);
}

public void jdbiQuery() {
    User user = User.builder()
            .id("1234")
            .emailAddresses(List.of("[email protected]", "[email protected]"))
            .build();
    String sqlTemplate =
            "SELECT id FROM Users WHERE id = :id AND email_address IN (:emailAddresses)";

    Jdbi jdbi = createJdbi(JDBC_URI, USERNAME, PASSWORD);

    List<String> userIds = jdbi.withHandle(
            handle -> handle.createQuery(sqlTemplate)
                            .bindBean(user)
                            .mapTo(String.class)
                            .list()
    );
}

The code above threw the exception: org.jdbi.v3.core.statement.UnableToCreateStatementException: No argument factory registered for type [java.util.List<java.lang.String>].

I read that this could be fixed by registering the array type as follows:

public void jdbiQuery() {
    .
    .
    Jdbi jdbi = createJdbi(JDBC_URI, USERNAME, PASSWORD);
    jdbi.registerArrayType(String.class, "varchar");
    .
    .
}

Indeed, that removed the exception, but then the final SQL statement generated was incorrect (notice how the IN clause is not correctly formatted).

SELECT id FROM Users WHERE id = '1234' AND email_address IN ('{"[email protected]","[email protected]"}')

Since the list identifiers to use the bindList functionality are enclosed in <>, I tried changing the SQL template to:

   .
   .
    String sqlTemplate =
            "SELECT id FROM Users WHERE id = :id AND email_address IN (<emailAddresses>)";
   .

which resulted in the following exception:

Caused by: org.jdbi.v3.core.statement.UnableToCreateStatementException: Undefined attribute for token '<emailAddresses>'

Does anyone know how to solve this issue? Any suggestion is welcome :)

Thanks!

0

There are 0 answers