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

Property mapping of nested Pojos #658

Closed khauser closed 5 years ago

khauser commented 5 years ago

I do have the following Pojos:

@Data
@MappedSuperclass
public abstract class BaseTestPlan
{
    @Id
    @Column(nullable = false, name = "tp_id")
    @NotNull
    private Long id;
    ...
@Data
@NoArgsConstructor(force = true)
@AllArgsConstructor
public class TopicOverviewItem
{
    private BaseTestPlan testPlan;

    @Column(name = "topic_name")
    private String topicName;
    ...

plus a jooq sql execution which results in:

select 
  "public"."dwh_topic_overview_entity"."test_plan_id" as "test_plan_id", 
  "public"."dwh_topic_overview_entity"."topic_name" as "topic_name", 
  ...
from "public"."dwh_topic_overview_entity"
...

From reading the Property Mapping documentation I came to this ResultSet mapping:

        ResultSetExtractor<List<TopicOverviewItem>> resultSetExtractor = JdbcTemplateMapperFactory.newInstance()
                        .addKeys("test_plan_id")
                        .addColumnProperty(c -> c.getName().startsWith("test_plan_id"),
                                        new RenameProperty(s -> s.replace("test_plan_id", "test_plan_tp_id")))
                        .newResultSetExtractor(TopicOverviewItem.class);

So test_plan for the property in TopicOverviewItem and tp_id as the nested column...

But this always results in:

org.simpleflatmapper.map.MapperBuildingException: Could not find eligible property for 'test_plan_id' on  class com.intershop.iste.bi.rest.resources.TopicOverviewItem 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:160)
    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:351)
    at org.simpleflatmapper.jdbc.JdbcMapperFactory$SetRowMapperFactory.newInstance(JdbcMapperFactory.java:339)
    at org.simpleflatmapper.map.mapper.DynamicSetRowMapper.getMapper(DynamicSetRowMapper.java:104)
    at org.simpleflatmapper.map.mapper.DynamicSetRowMapper.getMapperFromSet(DynamicSetRowMapper.java:94)
    at org.simpleflatmapper.map.mapper.DynamicSetRowMapper.forEach(DynamicSetRowMapper.java:83)
    at org.simpleflatmapper.jdbc.JdbcMapperFactory$DynamicJdbcSetRowMapper.forEach(JdbcMapperFactory.java:292)
    at org.simpleflatmapper.jdbc.spring.ResultSetExtractorImpl.extractData(ResultSetExtractorImpl.java:60)
    at org.simpleflatmapper.jdbc.spring.ResultSetExtractorImpl.extractData(ResultSetExtractorImpl.java:50)
    at com.intershop.iste.bi.repository.DwhTopicOverviewEntityRepositoryCustomImpl.queryByArtifactAndTopicAndEnvironment(DwhTopicOverviewEntityRepositoryCustomImpl.java:244)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359)
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy190.queryByArtifactAndTopicAndEnvironment(Unknown Source)
    at com.intershop.iste.bi.repository.DwhTopicOverviewRepositoryTest.test_queryByArtifactAndTopicAndEnvironment(DwhTopicOverviewRepositoryTest.java:91)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)

Some more surroundings:

    compile group: 'org.jooq', name: 'jooq', version: "3.11.11"
    compile group: 'org.simpleflatmapper', name: 'sfm-jooq', version: "6.7.0"

Do you have any suggestions about how to solve my Problem?

Thanks for yout help! Karsten

arnaudroger commented 5 years ago

could you try with

select 
  "public"."dwh_topic_overview_entity"."test_plan_id" as "test_plan_tp_id", 

in your query, different column alias? I think with the @column that might be what it would expect, if that does not work, I'll write a test for it and see.

khauser commented 5 years ago

Now it gives me:

java.lang.InstantiationError: com.intershop.iste.bi.persistence.BaseTestPlan
    at org.simpleflatmapper.reflect.generated.com.intershop.iste.bi.persistence.AsmBiInstantiatorBaseTestPlanFromResultSetAndMappingContext_I0.newInstance(Unknown Source)
    at org.simpleflatmapper.reflect.generated.com.intershop.iste.bi.persistence.AsmBiInstantiatorBaseTestPlanFromResultSetAndMappingContext_I0.newInstance(Unknown Source)
    at org.simpleflatmapper.map.mapper.AbstractMapper.map(AbstractMapper.java:22)
    at org.simpleflatmapper.map.mapper.MapperFieldMapperGetterAdapter.get(MapperFieldMapperGetterAdapter.java:36)
    at org.simpleflatmapper.map.getter.ContextualGetterBiFunction.apply(ContextualGetterBiFunction.java:65)
    at org.simpleflatmapper.reflect.generated.com.intershop.iste.bi.rest.resources.AsmBiInstantiatorTopicOverviewItemFromResultSetAndMappingContextIntodurationAndenvironmentAndfailedTestCasesAndfailedTestSuitesAndtestPlanAndtopicNameAndtotalTestCasesAndtotalTestSuites_I2.newInstance(Unknown Source)
    at org.simpleflatmapper.reflect.generated.com.intershop.iste.bi.rest.resources.AsmBiInstantiatorTopicOverviewItemFromResultSetAndMappingContextIntodurationAndenvironmentAndfailedTestCasesAndfailedTestSuitesAndtestPlanAndtopicNameAndtotalTestCasesAndtotalTestSuites_I2.newInstance(Unknown Source)
    at org.simpleflatmapper.map.mapper.AbstractMapper.map(AbstractMapper.java:22)
    at org.simpleflatmapper.map.mapper.ContextualSourceFieldMapperImpl.map(ContextualSourceFieldMapperImpl.java:38)
    at org.simpleflatmapper.map.impl.StaticMapperEnumerable.next(StaticMapperEnumerable.java:27)
    at org.simpleflatmapper.util.EnumerableSpliterator.forEachRemaining(EnumerableSpliterator.java:28)
    at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source)
    at com.intershop.iste.bi.repository.DwhTopicOverviewEntityRepositoryCustomImpl.queryByArtifactAndTopicAndEnvironment(DwhTopicOverviewEntityRepositoryCustomImpl.java:269)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359)
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy190.queryByArtifactAndTopicAndEnvironment(Unknown Source)
    at com.intershop.iste.bi.repository.DwhTopicOverviewRepositoryTest.test_queryByArtifactAndTopicAndEnvironment(DwhTopicOverviewRepositoryTest.java:91)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
arnaudroger commented 5 years ago

just check BaseTestPlan is a abstract class so it can instanitate it. you will need to defined an inheritance strategy https://simpleflatmapper.org/0205-inheritance-discriminator.html

if you don't have a discriminator column and one impl you can use

        XXXXMapperFactory.newInstance()
                .discriminator(
                        BaseTestPlan.class, 
                        builder ->   builder.when(rs -> true, BaseTestPlanImpl.class)
                )
                .newMapper(Foo.class);
khauser commented 5 years ago

Great tool man! This solved my OneToOne relation problem. Thanks