2016-02-01 1 views
1

J'essaye de mapper un DateMidnight dans un LocalDate en utilisant orika. Mais indépendamment de ce que j'essaie je reçois cette erreur ma.glasnost.orika.MappingException: No concrete class mapping defined for source class org.joda.time.chrono.ISOChronology. Mais il échoue uniquement sur le serveur jenkins (unix), pas localement (win).Orika mappage de jodatime DateMidnight

La cartographie DateMidnight-LocaleDate est configuré comme ceci:

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

J'ai essayé Quoiqu'il en soit l'ajout d'un mappage entre béton chronologies trouvés dans jodatime.

par exemple

ISOChronology -> ISOChronology

ISOChronology ->Chronology

Chronology ->ISOChronology

Chronology ->Chronology

utilisant le registerClassMap comme indiqué être faible:

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

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

Toute aide serait grandement appréciée

EDIT - Solution et plus infomation

Alors, j'ai trouvé une solution après l'enregistrement d'une première ObjectFactory pour Chronology en utilisant MapperFactory.registerObjectFactory.

Le code a ensuite échoué avec une exception expliquez comment 280 n'était pas une valeur valide pour hoursInDay lors de la création d'un LocaleDateTime. Maintenant, tous les cartographes ont été mis en place pour la carte DateMidnight-LocaleDate, pourquoi serait-il essayer d'initialiser un objet LocaleDateTIme ... Ci-dessous la classe Period il essayait de mapper (écrit de mémoire)

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(); 
    } 
} 

Le mapper de XMLPeriod à Period utilisé field("fom", "from") et field("to", "to").

Il s'avère que la stratégie de résolution des constructeurs d'Orika est basée sur une heuristique essayant de trouver le constructeur avec le plus grand nombre d'arguments qu'elle peut remplir. L'heuristique ne prend cependant pas en compte les mappages ou les convertisseurs que vous avez enregistrés, et regarde uniquement les noms de paramètres.

Depuis les deux derniers constructeurs ont le même rang. Il ignore ensuite le constructeur en utilisant LocaleDate, et essaie d'utiliser l'initialisation LocaleDateTime. Et puis échoue brutalement car il n'a pas de concept de l'ordre des arguments pour LocaleDateTime (et échouerait aussi à cause de ISOChonology être singleton comme, mais qui a été fixé)

Alors ... La solution à tous mes problèmes. ..

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

Ouais, renommer un argument résolu le problème ...

PS. Ce n'est probablement pas la meilleure solution à ce problème. Mais c'est une solution. Si quelqu'un sait comment cela peut être résolu d'une meilleure manière, s'il vous plaît faites le moi savoir.

+0

Comment êtes-vous le 'DateMidnight' Enregistrement - convertisseur>' de LocalDate'? Pouvez-vous montrer les haricots et les cartographies, aussi? Le code du convertisseur semble OK, donc Orika ne devrait pas essayer d'accéder à la chronologie à l'intérieur ... –

+0

Je peux le rechercher. Juste pour que nous puissions aider les futurs utilisateurs. J'étais cependant capable de comprendre quelque chose. Les classes 'Chronology' faisaient partie d'une correspondance entre' XMLPeriod' et 'Period'. 'XMLPeriod' utilisait' DateMidnight', et 'Period' voulait un' LocaleDate'. Cependant, il a également accepté 'LocaleDateTime' avec les mêmes noms de paramètres et spécificité. Puisque le constructeur acceptant 'LocaleDateTime' était des processus après le constateur avec' LocaleDate', il a utilisé ce constructeur à la place, et a donc manqué le mappage de 'DateMidnight' à' LocaleDate' et a tenté de le résoudre avec réflexion, – atomman

+1

Ajout d'une explication détaillée de ce qui semblait causer le problème. Mais encore, si vous connaissez une meilleure solution, je serais très heureux. Lorsque les noms des arguments ont soudainement cette liaison implicite, eh bien, chose un devoir de se retrouver dans la maintenance-enfer avec un regard de longue session de débogage. – atomman

Répondre

2

j'ai eu des problèmes similaires, avez-vous essayé la suite, peut-être il aide:

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