SimpleFlatMapper icon indicating copy to clipboard operation
SimpleFlatMapper copied to clipboard

Mapping sql-ResultSet to nested list structure

Open jimonthebarn opened this issue 5 years ago • 6 comments

This is less of an issue and more of a 'how can this be achieved'- type of question.

Im trying to map the data retrieved via a ResultSet to a nested target structure whose simplified, pseudo-code structure looks like this:

data class ParentEntity(
       var parentId : Int,
        var children: MutableList<ChildEntity>
) 

data class ChildEntity(
       var parentId: Int,
       var childId: Int,
       var propA: String,
       var propB: String

      //some static method to create child entity
      fun build(parentId, childId, propA, propB) : ChildEntity
)

The type of children property was String before and everything was working with the mapper based on the following configuration:

JdbcMapperFactory.newInstance()
       .addKeys("parentId")
       .addAlias("children_column_in_db", "children")
       .newMapper(ParentEntity::class.java)

Since the children property now needs to contain a complex type it was changed to ChildEntity. As explained in https://github.com/arnaudroger/SimpleFlatMapper/wiki/Errors_CSFM_GETTER_NOT_FOUND I adjusted the Mapper configuration like such to tell the mapper which column maps to which field:

JdbcMapperFactory.newInstance()
       .addKeys("parentId", "childId")
       .addAlias("parentId", "children.parentId")
       .addAlias("childId", "children.childId")
        .addAlias("propFromResultSetA", "children.propA")
       .addAlias("propFromResultSetB", "children.propB")
       // this is my poor attempt to add a getter to let simpleflatmapper know how to create the ChildEntity which is obviously wrong since I cant access all the columns required here 
       .addGetterForType(ChildEntity::class.java) {
              ContextualGetter<ResultSet, ChildEntity> { s, context ->
                     ChildEntity.build("", "", "", "") }
              }
       .newMapper(ParentEntity::class.java)

Upon execution simpleflatmapper reports: Could not find eligible property for 'children.parentId' on class com...ParentEntity.

If I understood correctly this type of mapping should be supported. Im sure I configured something wrong here and would greatly appreciate a hint on where my config attempt went wrong. :)

Cheers, Ben

jimonthebarn avatar Aug 12 '19 14:08 jimonthebarn

yes I think it should work, the only it would not work might be link to the build function if it can't figure out the name of the parameter, could you try with a constructor? to see if that the case?
what is the type of MutableList? is it eclipse collection? or kotlin list - that could also be the issue.

arnaudroger avatar Aug 12 '19 14:08 arnaudroger

I added the constructor to no avail though. Yep the MutableList is a kotlin built-in interface. I fiddled around a little bit with different types for the children property but the error remains.

jimonthebarn avatar Aug 13 '19 07:08 jimonthebarn

I’ll try to reproduce but I don’t think I have kotlin lost support yet

Sent from my iPhone

On 13 Aug 2019, at 08:03, Ben Roth [email protected] wrote:

I added the constructor to no avail though. Yep the MutableList is a kotlin built-in interface. I fiddled around a little bit with different types for the children property but the error remains.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

arnaudroger avatar Aug 13 '19 07:08 arnaudroger

I'm trying to reproduce the pb with the following code

class Issue674Test {
    @Test
    fun test() {

        val builder = JdbcMapperFactory.newInstance().useAsm(false)
                .addKeys("parentId", "childId")
                .addAlias("parentId", "children.parentId")
                .addAlias("childId", "children.childId")
                .addAlias("propFromResultSetA", "children.propA")
                .addAlias("propFromResultSetB", "children.propB")
                .newBuilder(ParentEntity::class.java)


        builder.addKey("parentId")
        builder.addKey("childId")
        builder.addMapping("propFromResultSetA")
        builder.addMapping("propFromResultSetB")


        val mapper = builder.mapper();


        println("mapper = ${mapper}")
    }
}

data class ParentEntity(
        var parentId : Int,
        var children: MutableList<ChildEntity>
)

data class ChildEntity(
        var parentId: Int,
        var childId: Int,
        var propA: String,
        var propB: String
)

using the builder - static mapper - to avoid having to setup the database but it seems to be working .... the MutableList is actually working would you mind trying to reproduce it using that test as a base?

arnaudroger avatar Aug 13 '19 11:08 arnaudroger

Sure I will. Whats the purpose of re-adding the keys after the instantiation of the builder? Do I need those as well? Great to hear that kotlin lists should be working out of the box already.

jimonthebarn avatar Aug 14 '19 16:08 jimonthebarn

no purpose redundant there ... my mistake

arnaudroger avatar Aug 15 '19 07:08 arnaudroger