DozerでNullPointerExceptionを取得せずに未設定のプロパティを値にマッピングする方法
質問
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、または何でも返します。
問題は、これがコンパイル時エラーではなく実行時エラーになることです。これを正しく解決したいです。
マップを実行することでnullをスキップできるDozerドキュメントを読みました。 -null =" false" が、これを機能させることができませんでした...
提案はありますか
解決
問題はドーザーではなく、ゲッターの隠された自動ボックス解除にあると思います:
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に実際にnull IDが含まれる場合は、ゲッター/セッターを変更して、プリミティブintではなく整数を取得/設定します。
-
Class1とClass2の両方にnull idを含めることはできず、これをクラス不変とみなす場合は、ゲッター/セッターおよび以下のいずれかでプリミティブint型を保持できます。
- get(" id")がnullにならないようにするには、コンストラクターで特定の値(0など)に初期化し、nullに設定できないようにします。
- または、getId()がnullの場合にデフォルト値を返すことを決定し、前述のとおりゲッターにnullチェックを追加します。
-
Class1にnull idがあり、Class2にはない場合、Class1のgetterおよびsetterにはintプリミティブではなくInteger型を使用する必要があり、デフォルト値を返すdozer CustomConverterを作成するソースフィールドがnullです。
よろしく
[編集] 以下は、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());
}
}