简体   繁体   中英

Orika mapping of jodatime DateMidnight

I'm trying to map a DateMidnight into a LocalDate using orika . But regardless of what I try i get this error ma.glasnost.orika.MappingException: No concrete class mapping defined for source class org.joda.time.chrono.ISOChronology . But it only fails on the jenkins server (unix), not locally (win).

The mapping from DateMidnight to LocaleDate is configured like this:

public LocaleDate convert(DateMidnight source, Type<? extends LocaleDate> destinationType) {
    if (source == null) { return null; }
    return new LocaleDate(source);
}

Anyhow I've tried adding a concrete mappings between chronologies found in jodatime.

Eg

ISOChronology -> ISOChronology

ISOChronology -> Chronology

Chronology -> ISOChronology

Chronology -> Chronology

using the registerClassMap as shown below:

mapperFactory.registerClassMap(mapperFactory.classMap(ISOChronology.class, ISOChronology.class).byDefault().toClassMap());

ISOChronology -> ISOChronology gives me exception while creating object factory for org.joda.time.chrono.ISOChronology .

Any help would be greatly appreciated

EDIT - Solution and more infomation

So, I found a solution after first registering a ObjectFactory for Chronology using MapperFactory.registerObjectFactory .

The code then failed with an exception explain how 280 was not a valid value for hoursInDay when creating a LocaleDateTime . Now, all mappers were set up to map from DateMidnight to LocaleDate , why would it try to initialize a LocaleDateTIme object... Below is the Period class it was trying to map to (written from memory)

public class Period {
    public final LocaleDate from;
    public final LocaleDate to;

    public Period() {}//Rank: 0

    public Period(LocaleDate from, LocaleDate to) {//Rank: 2000
        this.from = from;
        this.to = to;
    }

    public Period(LocaleDateTime from, LocaleDateTime to) {//Rank: 2000
        this.from = from.toLocaleDate();
        this.to = to.toLocaleDate();
    }
}

The mapper from XMLPeriod to Period used field("fom", "from") and field("to", "to") .

Turns out Orika's constructor resolving strategy is based on a heuristic trying to find the constructor with the greatest number of arguments which it can fulfill. The heuristic does however not take into account which mappings or converters you have registered, and is purely looking at parameter-names.

Since the last two constructors have the same rank. It then ignores the constructor using LocaleDate , and tries to use initialize LocaleDateTime . And then fails brutally since it has no concept of the ordering of arguments for LocaleDateTime ( and would also fail because of ISOChonology being singleton-like, but that was fixed)

So... The solution to all my problems...

//DONT change wtf name, orika-mappings will break.
public Period(LocaleDateTime from, LocaleDateTime wtf) {
    this.from = from.toLocaleDate();
    this.to = wtf.toLocaleDate();
}

Yeah, renaming a argument solved the problem...

PS. This probably isnt the best solution to this problem. But it is a solution. If anyone know how this can be solved in a better way, please let me know.

我遇到了类似的问题,您是否尝试了以下操作,也许有帮助:

factory.getConverterFactory().registerConverter(new PassThroughConverter(org.joda.time.Chronology.class));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM