aaberg / sql2o

sql2o is a small library, which makes it easy to convert the result of your sql-statements into objects. No resultset hacking required. Kind of like an orm, but without the sql-generation capabilities. Supports named parameters.
http://sql2o.org
MIT License
1.15k stars 229 forks source link

Please add support for Java8 java.time.LocalDate #282

Closed mvysny closed 7 years ago

mvysny commented 7 years ago

Thank you for your wonderful library, I'm integrating it into my framework (Vaadin on Kotlin) and it works flawlessly. One thing though: if I have a pojo with java.time.LocalDate, it seems that it cannot be mapped since reading such pojo from a database will result in

at sun.reflect.GeneratedMethodAccessor12.invoke(Unknown Source)
    at org.sql2o.reflection.MethodAccessorsGenerator$2.setProperty(MethodAccessorsGenerator.java:126)
    at org.sql2o.DefaultResultSetHandlerFactory$4.handle(DefaultResultSetHandlerFactory.java:180)
    at org.sql2o.PojoResultSetIterator.readNext(PojoResultSetIterator.java:34)
    at org.sql2o.ResultSetIteratorBase.safeReadNext(ResultSetIteratorBase.java:87)
    at org.sql2o.ResultSetIteratorBase.hasNext(ResultSetIteratorBase.java:52)
    at org.sql2o.Query.executeAndFetch(Query.java:455)
    at org.sql2o.Query.executeAndFetch(Query.java:441)

It seems that the type is correctly of type LocalDate, however actual value is java.sql.Date. I'm using H2, the database column type is DATE. Thanks!

mvysny commented 7 years ago

JDBC 4.2 are now required to support java.time.LocalDate in ResultSet.getObject(int columnIndex, Class<T> type) so perhaps we can use that to our advantage.

zapodot commented 7 years ago

@mvysny You are right about JDBC 4.2! If you are lucky enough to have a updated JDBC driver it works. At least it had no problem mapping from a H2 DATE field to a LocalDate field using an updated H2 driver in my test project If your chosen DBMS does not currently have an updated driver or you can't use it for some reason you may implement the org.sql2o.convertes.Converter interface yourself

zapodot commented 7 years ago

@mvysny: I have added a page on the Wiki on how to implement and enable a custom datatype Mapper https://github.com/aaberg/sql2o/wiki/Implementing-and-using-custom-converters Good luck!

mvysny commented 7 years ago

Thanks, that looks good! One question though: How can I add converters to already existing Quirks object, returned by the QuirksDetector.forURL(hikariConfig.jdbcUrl) call?

zapodot commented 7 years ago

You can use the service loader mechanism instead to provide your custom Converter. I.E add a text file called org.sql2o.converters.ConvertersProvider to the META-INF/services on your classpath. Add the classname of your custom Converter implementation to it on a single line and it will be available in your runtime. I will update the documentation on the Wiki :-)

mvysny commented 7 years ago

That worked like a charm, thank you!

srbattula commented 6 years ago

I am using Spring Boot Starter JDBC with Sql20. Can you suggest a way to handle this?

org.springframework.boot spring-boot-starter-jdbc
srbattula commented 6 years ago

This helped me to resolve this problem https://github.com/aaberg/sql2o/wiki/Implementing-and-using-custom-converters But it would be nice without having this work arounds by part of the library.

diyfr commented 5 years ago

Postgres table property 'DATE'
Object with LocalDate property

On Class MethodAcessorsGenerator, Method Setter newSetter
I see
method setDate(java.time.LocalDate) type= java.time.LocalDate value = java.sql.Date -> IllegalArgumentException ClassCastException

No LocalDate Converter found in org.sql2o.converters.Convert.java

Or @srbattula in documentation you write :

Hint: if you have an updated JDBC driver you don't need to do this by hand as mapping to java.time.LocalDate should work out of the box.

PostgreSql documentation

srbattula commented 5 years ago

You could use the following snipped to use LocalDate:

public class LocalDateConverter implements Converter { @Override public LocalDate convert(final Object val) throws ConverterException { if (val instanceof java.sql.Date) { return ((java.sql.Date) val).toLocalDate(); } else { return null; } }

@Override
public Object toDatabaseParam(final LocalDate val) {
    if (val == null) {
        return null;
    } else {
        return new

java.sql.Date(val.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()); } } }

Thanks & Regards

M: +91 7032643557 W: http://www.srithripurasoft.com

On Thu, Apr 11, 2019 at 6:43 PM Stéphane notifications@github.com wrote:

  • Java version 8
  • Sql2o version 1.6.0
  • Sql2o-postgres version 1.6.0
  • Postgres JDBC version 42.2.5 (JDBC 4.2)

Postgres table property 'DATE' Object with LocalDate property

On Class MethodAcessorsGenerator, Method Setter newSetter I see method setDate(java.time.LocalDate) type= java.time.LocalDate value = java.sql.Date -> IllegalArgumentException ClassCastException

No LocalDate Converter found in org.sql2o.converters.Convert.java

Or @srbattula https://github.com/srbattula in documentation you write :

Hint: if you have an updated JDBC driver you don't need to do this by hand as mapping to java.time.LocalDate should work out of the box.

PostgreSql documentation https://jdbc.postgresql.org/documentation/head/8-date-time.html

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aaberg/sql2o/issues/282#issuecomment-482108384, or mute the thread https://github.com/notifications/unsubscribe-auth/AITcuu2dZj7yaALQnAVir608OF5PMX8hks5vfzTggaJpZM4ORzeG .