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

Many-to-one relationship - Could not find eligible property [...] #660

Closed romqu closed 5 years ago

romqu commented 5 years ago

Hello,

first off all: Thank you for the great library! I apologize in advance if this turns out to be a stupid question. I'm trying to get a simple one-to-one relationship to work, but I fail to figure it out.

I looked at the issue here, but it didn't quite help.

Kotlin: 1.3.31 Spring Boot: 2.2.0-Snapshot Jooq: 3.11.11

The data (pojos) classes:

data class ProductCategoryJdbcEntity(

        val id: Long,

        val name: String
)
data class ProductJdbcEntity(

        val id: Long,

        val name: String,

        val quantity: Double,

        val minQuantity: Double,

        val productCategoryId: Long,

        val productCategoryJdbcEntity: ProductCategoryJdbcEntity
)

The mapper:

JdbcMapperFactory
    .newInstance()
    .addKeys("id",
             "product_category_id",
             "product_category_pk",
             "product_category_name")
   .addAlias("product_category_pk", "categoryId")
   .addAlias("product_category_name", "categoryName")
   .addAlias("product_category_id", "productCategoryId")
   .addAlias("min_quantity", "minQuantity")
   .newMapper(ProductJdbcEntity::class.java)

The query:

dsl.select(PRODUCT.ID,
           PRODUCT.NAME,
           PRODUCT.QUANTITY,
           PRODUCT.MIN_QUANTITY,
           PRODUCT.PRODUCT_CATEGORY_ID,
           PRODUCT_CATEGORY.ID.`as`("product_category_pk"),
           PRODUCT_CATEGORY.NAME.`as`("product_category_name"))
    .from(PRODUCT)
    .join(PRODUCT_CATEGORY)
    .on(PRODUCT_CATEGORY.ID
        .eq(PRODUCT.PRODUCT_CATEGORY_ID))
    .orderBy(PRODUCT.ID)
    .seek(key)
    .limit(limit)

The error message:

org.simpleflatmapper.map.MapperBuildingException: Could not find eligible property for 'categoryId' on  class de.romqu.inventory.data.product.ProductJdbcEntity not found  See https://github.com/arnaudroger/SimpleFlatMapper/wiki/Errors_PROPERTY_NOT_FOUN

I am obviously missing something. Could you please help me out?

Thank you!

arnaudroger commented 5 years ago

Ho no worries so you add an alias for product_category_pk to categoryId. seems that there is 2 properties that matches that, sfm will only be able to put in one place. the message says it looked for a categoryId prop on ProductJdbcEntity but did not find one. if you wanted it to go into ProductJdbcEntity.productCategoryId the alias need to be

.addAlias("product_category_pk", "productCategoryId")

if you want it in the ProductJdbcEntity.productCategoryJdbcEntity.id then

.addAlias("product_category_pk", "productCategoryJdbcEntity_id ")

if you want it in both, you 'll need to duplicate the column - I'll check but I think that the case -

dsl.select(PRODUCT.ID,
           PRODUCT.NAME,
           PRODUCT.QUANTITY,
           PRODUCT.MIN_QUANTITY,
           PRODUCT.PRODUCT_CATEGORY_ID,
           PRODUCT_CATEGORY.ID.`as`("productCategoryId"), 
           PRODUCT_CATEGORY.ID.`as`("productCategoryJdbcEntity_id"),
romqu commented 5 years ago

Hi,

thank you for your fast reply. I am an complete idiot. It's not an one-to-one, instead it's a many-to-one relationship. I am really, really sorry. :/

But it does not change the structure off the data classes.

I tried what you suggested and got the following error:

org.simpleflatmapper.map.MapperBuildingException: Could not find eligible property for 'productCategoryJdbcEntity_id' on  class de.romqu.inventory.data.product.ProductJdbcEntity not found  See https://github.com/arnaudroger/SimpleFlatMapper/wiki/Errors_PROPERTY_NOT_FOUND

Alright, I got it working:

JdbcMapperFactory
    .newInstance()
    .addKeys("id",
             "product_category_id",
             "product_category_pk",
             "product_category_name")
    .addAlias("product_category_pk", "productCategoryJdbcEntity_id")
    .addAlias("product_category_name", "productCategoryJdbcEntity_name")
    .addAlias("product_category_id", "productCategoryId")
    .addAlias("min_quantity", "minQuantity")
    .newMapper(ProductJdbcEntity::class.java)

I misunderstood how the 'alias' works. I apologize for the inconvenience.