Dozer mapping JodaTime property not working as expected
Asked Answered
H

5

13

I am using Dozer to map between a Document class to DocumentManagementBean class, both of my own making. Both have a property, with getters and setters, of Joda DateTime type, called dateAdded.

When Document object d has property dateAdded=x, calling mapper.map(d, DocumentManagementBean.class) all fields get auto-mapped correctly (since I have full control over code base I am able to get away with no dozer-config and rely simply on matching property names), EXCEPT the dateAdded field, where the new DocumentManagementBean dmb ends up with the current DateTime in its dateAdded property, instead of x from the d object.

I am expecting Dozer to try to call

dmb.setDateAdded(d.getDateAdded());

and just bring the value of dateAdded from source to target, but it seems to be creating new DateTime for dmb object an then leaving it alone.

Can anyone shed some light on this for me please?

Hacking answered 17/8, 2012 at 22:9 Comment(0)
M
16

The basic problem is that Dozer creates a new blank instance of DateTime, via new DateTime(), and thats how you end up with the current date/time instead of the original one. There might be multiple solutions, I usually went with a customconverter, globally defined:

    <converter type="de.kba.resper.customconverter.DateTimeCustomConverter">
        <class-a>org.joda.time.DateTime</class-a>
        <class-b>org.joda.time.DateTime</class-b>
    </converter>

and

public class DateTimeCustomConverter extends DozerConverter<DateTime, DateTime> {

    public DateTimeCustomConverter() {
        super(DateTime.class, DateTime.class);
    }

    @Override
    public DateTime convertTo(final DateTime source, final DateTime destination) {

        if (source == null) {
            return null;
        }

        return new DateTime(source);
    }

    @Override
    public DateTime convertFrom(final DateTime source, final DateTime destination) {

        if (source == null) {
            return null;
        }

        return new DateTime(source);
        }

}

It may overdo it, though :)

Mattins answered 23/8, 2012 at 8:51 Comment(2)
thanks, i came up with something similar but felt it's not quite right so waited if someone would perhaps provide a cleaner solution. Thanks again!Everlasting
IMHO there is no sense in Dozer converter, because DateTime is immutable. So copy-by-reference solution should be preferred over custom conveterUrinate
O
14

You probably don't need it anymore, but Dozer provides the chance to copy an object by reference, at least with the latest version (now, this version is 5.4.0). Copying by reference is what you are looking for.

<field copy-by-reference="true">
  <a>copyByReference</a>
  <b>copyByReferencePrime</b>
</field>

Documentation: http://dozer.sourceforge.net/documentation/copybyreference.html

Oquassa answered 7/1, 2013 at 9:54 Comment(1)
Yep, simple solution that works great for immutables.Valentinvalentina
M
5

Set a copy-by-reference global property in your xml file

    <copy-by-references>
        <copy-by-reference>
            org.joda.time.LocalDate
        </copy-by-reference>
        <copy-by-reference>
            org.joda.time.LocalDateTime
        </copy-by-reference>
    </copy-by-references>
Minutia answered 26/9, 2014 at 13:57 Comment(2)
Merci Pras, t'es mon héros :)Tendency
This fixed it for me, seems like the cleanest solutionTimehonored
O
0

It is possible to do it but you will have to add some configuration:

<field>
  <a set-method="placeValue" get-method="buildValue">value</a>
  <b>value</b>  
</field>

Here is more information: http://dozer.sourceforge.net/documentation/custommethods.html

Dos some one knows how to do tins with annotations?

Otorhinolaryngology answered 23/8, 2012 at 8:42 Comment(0)
M
0

I think the root cause is that DateTime is immutable, so the deep copy cannot be done (see https://github.com/DozerMapper/dozer/issues/216).

That's why you have to use a converter or copy it by reference.

Mantel answered 19/9, 2017 at 14:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.