Je crois que le problème est pas dozer, mais dans l'auto-unboxing caché dans votre getter:
public int getId()
{
return (Integer)get("id");
}
(entier) get ("id") est implicitement jeté dans un entier parce que le type de retour de votre méthode est "int".
Cela fonctionnera dans la plupart des cas ... SAUF lorsque le résultat est nul, auquel cas vous obtenez une exception NullPointerException car un int peut ne jamais être nul.
Il en résulte NullPointerExceptions cachés ... Plus d'infos ici: http://www.theserverside.com/blogs/thread.tss?thread_id=41731
Pour résoudre ce problème, vous avez plusieurs choix:
Si Class1 et Class2 peuvent en effet contenir un identifiant nul, vous vouloir modifier vos getters/setters pour obtenir/définir des entiers au lieu des ints primitifs.
Si les deux Class1 et Class2 ne doivent jamais contenir un identifiant nul, et vous considérez ceci comme une classe invariant, vous pouvez garder le type primitif int dans le getter/setter et:
- Assurez-vous get ("id") ne sera jamais nul, en l'initialisant à une valeur spécifique (telle que 0) dans le constructeur), et en s'assurant que rien ne peut le mettre à null.
- Ou décider que getId() retournera une valeur par défaut si null, et ajouter une vérification nulle dans le getter comme vous l'avez dit.
Si Class1 peut avoir un identifiant nul, mais Classe2 ne peut pas, vous devriez avoir des apporteurs de classes 1 et setters utiliser un type entier au lieu d'un int primitif, et vous devez créer un CustomConverter de bulldozer qui retourne une valeur par défaut lorsque le champ source est nul.
Cordialement
[EDIT] Voici le code de test qui montre que Dozer ne l'ignore nulls de cartographie lorsqu'on lui a demandé à:
src/com/test/dozer/Class1.java:
package com.test.dozer;
import com.extjs.gxt.ui.client.data.BaseModelData;
public class Class1 extends BaseModelData {
// Notice the return type here: "Integer" and *not* int
// Returning int throws a NullPointerException when get("id") is null!
public Integer getId() {
return (Integer) get("id");
}
public void setId(Integer id) {
set("id", id);
}
}
src/com/test/dozer/Class2.java:
package com.test.dozer;
public class Class2 {
private int id;
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
src/dozerMappingFile.xml:
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">
<configuration>
<stop-on-errors>true</stop-on-errors>
<date-format>MM/dd/yyyy HH:mm</date-format><!-- default dateformat will apply to all class maps unless the class mapping explicitly overrides it -->
<wildcard>true</wildcard><!-- default wildcard policy that will apply to all class maps unless the class mapping explicitly overrides it -->
</configuration>
<mapping map-null="false">
<class-a>com.test.dozer.Class1</class-a>
<class-b>com.test.dozer.Class2</class-b>
</mapping>
</mappings>
src/com/te st/dozer/DozerTest.java:
package com.test.dozer;
import java.util.Arrays;
import junit.framework.Assert;
import org.dozer.DozerBeanMapper;
import org.junit.Before;
import org.junit.Test;
public class DozerTest {
private DozerBeanMapper mapper;
@Before
public void setUp() {
mapper = new DozerBeanMapper(Arrays.asList("dozerMappingFile.xml"));
}
/**
* Verifies that class1's id is mapped into class2's id when not null.
*/
@Test
public void testMappingWhenIdNotNull() {
Class1 class1 = new Class1();
class1.setId(1);
Class2 class2 = new Class2();
class2.setId(2);
mapper.map(class1, class2);
Assert.assertEquals(1, class2.getId());
}
/**
* Verifies that class2's id is not set to null when class1's id is null.
*/
@Test
public void testMappingWhenIdIsNull() {
Class1 class1 = new Class1();
Class2 class2 = new Class2();
class2.setId(2);
mapper.map(class1, class2);
Assert.assertEquals(2, class2.getId());
}
}
Je suis d'accord avec tout ce que vous dites, mais ce que je comprends qu'il est aussi possible d'avoir bulldozer sauter mappings valeurs NULL. De cette façon, le logiciel de cartographie ne mappe pas les champs invalides. –
Il est en effet possible d'avoir des mappings null de Dozer, en utilisant le paramètre map-null = "false". Le problème est que Dozer appellera getId() pour déterminer s'il est nul ou non, et sinon il le mappera. Mais getId() échouera en raison de l'auto-unboxing de null à int ... Si vous remplacez votre getter pour retourner "Integer" au lieu de "int", cela fonctionne. Je vais modifier ma réponse ci-dessus avec le test pour le montrer. –