Frage

Dozer Mit zwei Objekten auf der Karte, die ich habe:

/**
/* This first class uses the GXT (ExtJS) framework
**/
Class1 extends BaseModelData
{
    public int getId()
    {
        return (Integer)get("id");
    }

    public void setId(int id)
    {
        set("id", id);
    }

    // more properties
}

Class2
{
    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    // more properties
}

Wenn ich nicht die Id in der ersten Klasse festgelegt (durch class1.setId () aufgerufen wird) ist das Ergebnis eine Nullpointer von Dozer. Ich verstehe, dass dies richtig ist, wie get ( „id“) null sein würde.

ich natürlich kann dies lösen, indem Sie einen Scheck für null setzen, und die Rückkehr -1 oder 0, oder was auch immer.

Das Problem ist, dass dieser dann einen Laufzeitfehler wird eher als ein Kompilierung Fehler. Ich würde viel lieber diese richtig lösen.

Jetzt habe ich gelesen in der Dozer Dokumentation, die Sie kann es null überspringen haben Karte, indem Sie -Null = „false“ , aber ich konnte nicht an der Arbeit ...

Irgendwelche Vorschläge?

War es hilfreich?

Lösung

Ich glaube, das Problem ist nicht in Planierraupe, aber in dem versteckten Auto-Unboxing in Ihrem Getter:

   public int getId()
{
    return (Integer)get("id");
}

(Integer) erhalten ( "id") wird implizit in einen int geworfen, weil der Rückgabetyp Ihrer Methode ist "int".

Dies wird in den meisten Fällen funktioniert ... außer wenn das Ergebnis null, in dem Fall, dass Sie eine Nullpointer bekommen, weil ein int nie null sein kann.

Dies führt zu versteckten Nullpointerexceptions ... Mehr Infos hier: http: / /www.theserverside.com/blogs/thread.tss?thread_id=41731

Um dies zu beheben, haben Sie mehrere Möglichkeiten:

  • Wenn Class1 und Class2 in der Tat eine Null-ID enthalten, Sie möchten Ihre Getter / Setter ändern, um get / set Ganze Zahlen statt primitive Ints.

  • Wenn beide Class1 und Class2 sollen nie einen Null-ID enthalten, und Sie halten dies für eine Klasseninvariante sein, können Sie den primitiven int-Typen in dem Getter / Setter halten können und entweder:

    • Stellen Sie sicher, get ( „id“) wird nie Null sein, indem es bis zu einem gewissen bestimmten Wert (zB 0) im Konstruktor) initialisiert, und sicherzustellen, dass nichts mich festlegen kann auf null.
    • eine Null-Kontrolle in dem Getter
    • Oder entscheiden, dass getId () ein Standardwert, wenn null zurück, und fügen Sie wie Sie gesagt haben.
  • Wenn Class1 kann eine Null-ID haben, aber Class2 nicht, sollten Sie Class1 die Getter und Setter verwenden, um einen Integer-Typ anstelle eines int primitive haben, und Sie sollten eine Planierraupe CustomConverter erstellen, die einen Standardwert zurückgibt, wenn die Quellfeld ist null.

Viele Grüße


[EDIT] Hier ist der Testcode, der zeigt, dass Dozer tut ignorieren NULL-Werte-Mapping, wenn gefragt:

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

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top