arnaudroger / SimpleFlatMapper

Fast and Easy mapping from database and csv to POJO. A java micro ORM, lightweight alternative to iBatis and Hibernate. Fast Csv Parser and Csv Mapper
http://simpleflatmapper.org
MIT License
437 stars 76 forks source link

Immutable implementation detection #609

Closed arnaudroger closed 5 years ago

arnaudroger commented 5 years ago

copy from https://github.com/arnaudroger/SimpleFlatMapper/issues/574#issuecomment-462845517

This is very nice, thanks for the quick response. Unfortunately, now I see I misread the issue. What I would like to do is to use the interface and have sfm use the immutable implementation automatically:

@Value.Immutable
public interface ReallyUsefulInformation {
    String info();
}

public interface ReallyUsefulInformationDao {
    @SqlQuery("...")
    ReallyUsefulInformation getReallyUsefulInformation();
}

Maybe I could help you build sfm-immutables to actually detect @Value.Immutable and use the generated immutable class?

This is the error I get:

org.simpleflatmapper.map.MapperBuildingException: Could not find eligible property for 'info' on  interface ...ReallyUsefulInformation not found  See https://github.com/arnaudroger/SimpleFlatMapper/wiki/Errors_PROPERTY_NOT_FOUND
    at org.simpleflatmapper.map.error.RethrowMapperBuilderErrorHandler.propertyNotFound(RethrowMapperBuilderErrorHandler.java:26)
    at org.simpleflatmapper.map.mapper.PropertyMappingsBuilder._addProperty(PropertyMappingsBuilder.java:105)
    at org.simpleflatmapper.map.mapper.PropertyMappingsBuilder.addProperty(PropertyMappingsBuilder.java:69)
    at org.simpleflatmapper.map.mapper.DefaultConstantSourceMapperBuilder.addMapping(DefaultConstantSourceMapperBuilder.java:159)
    at org.simpleflatmapper.map.mapper.SetRowMapperBuilderImpl.addMapping(SetRowMapperBuilderImpl.java:206)
    at org.simpleflatmapper.map.mapper.MapperBuilder.addMapping(MapperBuilder.java:142)
    at org.simpleflatmapper.map.mapper.MapperBuilder.addMapping(MapperBuilder.java:152)
    at org.simpleflatmapper.jdbc.JdbcMapperFactory$SetRowMapperFactory.newInstance(JdbcMapperFactory.java:344)
    at org.simpleflatmapper.jdbc.JdbcMapperFactory$SetRowMapperFactory.newInstance(JdbcMapperFactory.java:332)
    at org.simpleflatmapper.map.mapper.DynamicSetRowMapper.getMapper(DynamicSetRowMapper.java:104)
    at org.simpleflatmapper.jdbc.JdbcMapperFactory$DynamicJdbcSetRowMapper.getMapper(JdbcMapperFactory.java:299)
    at org.simpleflatmapper.jdbi3.DynamicRowMapper.specialize(DynamicRowMapper.java:25)
    at org.jdbi.v3.core.result.ResultSetResultIterator.<init>(ResultSetResultIterator.java:38)
    at org.jdbi.v3.core.result.ResultIterable.lambda$of$0(ResultIterable.java:53)
    at org.jdbi.v3.core.result.ResultIterable.findFirst(ResultIterable.java:116)
    at org.jdbi.v3.sqlobject.statement.internal.ResultReturner$CollectedResultReturner.mappedResult(ResultReturner.java:276)
    at org.jdbi.v3.sqlobject.statement.internal.SqlQueryHandler.lambda$configureReturner$0(SqlQueryHandler.java:54)
    at org.jdbi.v3.sqlobject.statement.internal.CustomizingStatementHandler.invoke(CustomizingStatementHandler.java:155)
    at org.jdbi.v3.sqlobject.statement.internal.SqlQueryHandler.invoke(SqlQueryHandler.java:26)
    at org.jdbi.v3.sqlobject.SqlObjectFactory.lambda$null$13(SqlObjectFactory.java:158)
    at org.jdbi.v3.core.internal.JdbiThreadLocals.invokeInContext(JdbiThreadLocals.java:27)
    at org.jdbi.v3.core.LazyHandleSupplier.lambda$invokeInContext$1(LazyHandleSupplier.java:72)
    at org.jdbi.v3.core.internal.JdbiThreadLocals.invokeInContext(JdbiThreadLocals.java:27)
    at org.jdbi.v3.core.LazyHandleSupplier.invokeInContext(LazyHandleSupplier.java:71)
    at org.jdbi.v3.sqlobject.SqlObjectFactory.lambda$createInvocationHandler$14(SqlObjectFactory.java:157)
    at org.jdbi.v3.core.OnDemandExtensions.invoke(OnDemandExtensions.java:76)
    at org.jdbi.v3.core.OnDemandExtensions.lambda$null$0(OnDemandExtensions.java:63)
    at org.jdbi.v3.core.internal.JdbiThreadLocals.invokeInContext(JdbiThreadLocals.java:27)
    at org.jdbi.v3.core.OnDemandExtensions.lambda$null$1(OnDemandExtensions.java:62)
    at org.jdbi.v3.core.Jdbi.withExtension(Jdbi.java:439)
    at org.jdbi.v3.core.OnDemandExtensions.lambda$create$2(OnDemandExtensions.java:61)
    at com.sun.proxy.$Proxy42.getReallyUsefulInformation(Unknown Source)
    at ...ReallyUsefulInformationFacade.getReallyUsefulInformation(ReallyUsefulInformationFacade.java:18)
...
paulolieuthier commented 5 years ago

Give me directions and I will try.

arnaudroger commented 5 years ago

So the way I see it implemented would be in the reflection service before returning the objectmetadata it would check for the annotation using reflection and try to figure out the immutable class and return an objectmetadata on that one. I should be able to do that quickly the annotations are their at runtime. There is also a style annotation to check that can override the name. If the immutable is not public the we fall back on the interface.

arnaudroger commented 5 years ago

@paulolieuthier I think I've got it there needed to use asm as the annotation are not RUNTIME retention

paulolieuthier commented 5 years ago

@arnaudroger awesome. Just tested it, works perfectly.

arnaudroger commented 5 years ago

great! thanks for the feedback!