atos1990 / orika

Automatically exported from code.google.com/p/orika
0 stars 0 forks source link

want to have option to not set target object property when property value in the source object is null #38

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

I am working to replace the dozer bean mapping solution with orika solution for 
conversion performance purpose. I made a bridge to migrate the dozer mapping 
solution to orika with a minor existing dozer mapping configuration changes and 
hide the details for the business layer.  And I am almost there except one 
issue. Our old project was written with EJB and Hibernate. Most of the PO 
entities (persistent objects) contain nested type objects. For example:

public class BasCustomer extends AbstractBO
    @ManyToOne(fetch = FetchType.LAZY)
    private BasCantonInfo area;
   .....
}

public BasCantonInfo{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "BAS_CANTONINFO_SEQ")
    private Long id;
   .....
}

My mapping BasCustomerVO ----> BasCustomer 

            <field>
                <a>area.id</a>  <!-- BasCustomer  -->
                <b>areaId</b>   <!-- BasCustomerVO -->
            </field>
            <field type="one-way" >
                <a>area.name</a>   <!-- BasCustomer  -->
                <b>areaName</b>   <!-- BasCustomerVO -->
            </field>

In my generated class OrikaBasCustomerVoBasCustomerMapper1884032229682941, I 
see that, the code segment for BasCustomerVO.areaId  ---> BasCustomer.area.id 
is as bellow. 

if (((com.best.oasis.genidc.biz.base.model.BasCantonInfo) destination
                .getArea()) == null)
            destination
                    .setArea((com.best.oasis.genidc.biz.base.model.BasCantonInfo) mapperFacade
                            .newObject(source, usedTypes[0], mappingContext));

((com.best.oasis.genidc.biz.base.model.BasCantonInfo) destination
                .getArea()).setId(((java.lang.Long) source.getAreaId()));

So when the BasCustomerVO.areaId and BasCustomerVO.areaName property both null, 
I will get a  BasCustomer.area nested type object, but with all property null. 
To be more specifically, BasCustomer.area.id =null, BasCustomer.area.name =null 
and so on.  Then hibernate will take action to try to save the BasCantonInfo 
instance “area” because it thinks “area” should be a new entity object 
but it will be never successfully saved for it only contains null properties.

So for me, my expectation result of BasCustomer.area in this case is 
BasCustomer.area= null;

And if the generated code be

        if (source.getAreaId() != null) {
            if (((com.best.oasis.genidc.biz.base.model.BasCantonInfo) destination
                    .getArea()) == null)
                destination
                        .setArea((com.best.oasis.genidc.biz.base.model.BasCantonInfo) mapperFacade
                                .newObject(source, usedTypes[0], mappingContext));

            ((com.best.oasis.genidc.biz.base.model.BasCantonInfo) destination
                    .getArea()).setId(((java.lang.Long) source.getAreaId()));
        }

maybe also make sence. I don't know whether this will break the other use 
cases.  Or maybe we can make this behavior configurable for flexibility purpose.

And also for String type conversion, the generated code segment is 

What is the expected output? What do you see instead?

What version of the product are you using? On what operating system?

Please provide any additional information below.

Original issue reported on code.google.com by wangbt5...@gmail.com on 17 Aug 2012 at 12:28

GoogleCodeExporter commented 9 years ago
Can you please show me what kind of code you want to be generated, just to 
understand your needs ?

Original comment by elaat...@gmail.com on 18 Aug 2012 at 11:16

GoogleCodeExporter commented 9 years ago
Hi 
the expecting generated code can be like this
And if the generated code be

        if (source.getAreaId() != null) {   // this is what I am expecting.
            if (((com.best.oasis.genidc.biz.base.model.BasCantonInfo) destination
                    .getArea()) == null)
                destination
                        .setArea((com.best.oasis.genidc.biz.base.model.BasCantonInfo) mapperFacade
                                .newObject(source, usedTypes[0], mappingContext));

            ((com.best.oasis.genidc.biz.base.model.BasCantonInfo) destination
                    .getArea()).setId(((java.lang.Long) source.getAreaId()));
        }  // this is what I am expecting.

Original comment by wangbt5...@gmail.com on 20 Aug 2012 at 10:10

GoogleCodeExporter commented 9 years ago
Please at this Unit test attached to the comment, if it fit your needs.
PS: I have a fix wich do not create a new object if all properties are null and 
set destination to null,
still the case when you have a primitive property and all others are null then 
orika will will create new object

Original comment by elaat...@gmail.com on 21 Aug 2012 at 8:06

Attachments:

GoogleCodeExporter commented 9 years ago
Hi Sadi
This fits my requirment. Thanks a lot. May I know which release this changes 
will be in?

Original comment by wangbt5...@gmail.com on 22 Aug 2012 at 7:31

GoogleCodeExporter commented 9 years ago
I will try to make a release by the end of the week,
I want to bundle some other fixes :)

Please stay tuned, one more time thank you!

Original comment by elaat...@gmail.com on 22 Aug 2012 at 7:36

GoogleCodeExporter commented 9 years ago

Original comment by elaat...@gmail.com on 22 Aug 2012 at 8:52

GoogleCodeExporter commented 9 years ago

Original comment by elaat...@gmail.com on 22 Aug 2012 at 8:52

GoogleCodeExporter commented 9 years ago
applied same fix and test case to 1.2.0 branch

Original comment by matt.deb...@gmail.com on 23 Aug 2012 at 5:22