1

Dozerを使用して2つのオブジェクトをマッピングすると、次のようになります。

/**
/* 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
}

(class1.setId()を呼び出して)最初のクラスでIDを設定しない場合、結果はDozerからのNullPointerExceptionになります。get( "id")がnullになるため、これが正しいことを理解しています。

もちろん、nullのチェックを入れて、-1や0などを返すことで、これを解決できます。

問題は、これがコンパイル時エラーではなく実行時エラーになることです。私はこれを正しく解決したいと思っています。

これで、 Map-null = "false"を実行することでnullをスキップできることをDozerのドキュメントで読みましたが、これを機能させることができませんでした...

助言がありますか?

4

1 に答える 1

1

問題はドーザーではなく、ゲッターの隠された自動開梱にあると思います。

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

(Integer)get( "id")は、メソッドの戻り型が "int"であるため、暗黙的にintにキャストされます。

これはほとんどの場合に機能します...結果がnullの場合を除きます。この場合、intがnullになることはないため、NullPointerExceptionが発生します。

これにより、NullPointerExceptionsが非表示になります...詳細はこちら:http ://www.theserverside.com/blogs/thread.tss?thread_id = 41731

これを解決するには、複数の選択肢があります。

  • Class1とClass2に実際にnullIDが含まれている可能性がある場合は、ゲッター/セッターを変更して、プリミティブintではなく整数を取得/設定する必要があります。

  • Class1とClass2の両方にnullIDを含めるべきではなく、これをクラス不変と見なす場合は、プリミティブint型をgetter/setterに保持することができます。

    • get( "id")がnullにならないように、コンストラクターで特定の値(0など)に初期化して、nullに設定できるものがないことを確認してください。
    • または、getId()がnullの場合にデフォルト値を返すことを決定し、前述のようにgetterにnullチェックを追加します。
  • Class1にnullIDがあるが、Class2にはない場合は、Class1のゲッターとセッターにintプリミティブではなく整数型を使用させ、ソースフィールドがnullのときにデフォルト値を返すドーザーCustomConverterを作成する必要があります。

よろしく


[編集]これは、Dozerが要求されたときにマッピングnullを無視することを示すテストコードです。

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

}
于 2009-09-10T20:32:38.627 に答える