Java 8 introduced the superior LocalDate and LocalDateTime, but JDBI does not work so nicely with them. You’ll find errors like:
org.skife.jdbi.v2.exceptions.UnableToExecuteStatementException: org.h2.jdbc.JdbcSQLException: Cannot parse "TIMESTAMP" constant "aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e0060d0c2c2c0ac9d74078"
In order to bind the parameters of a JDBI DAO for these Objects, you’ll need to implement your own Binder.
import org.skife.jdbi.v2.SQLStatement; import org.skife.jdbi.v2.sqlobject.Bind; import org.skife.jdbi.v2.sqlobject.Binder; import java.sql.Timestamp; import java.time.LocalDateTime; public class LocalDateTimeBinder implements Binder<Bind, LocalDateTime> { @Override public void bind(SQLStatement<?> q, Bind bind, LocalDateTime localDateTime) { q.bind(bind.value(), Timestamp.valueOf(localDateTime)); } }
Using the Binder
And in usage, set the binder for the @Bind
annotation. This example also includes how an auto-incremented ID for a table will be returned when doing an insert.
@GetGeneratedKeys @SqlUpdate("INSERT INTO my_table (name, created_date) VALUES (:name, :createdDate)") int create(@Bind("name") String name, @Bind(value = "createdDate", binder = LocalDateTimeBinder.class) LocalDateTime createdDate);
JDBI Binders are easy to implement, you’ll just want to be sure you’re using java.sql.Timestamp vs java.sql.Date appropriately, hint hint the latter for LocalDate.