1

使用推土机映射两个对象,我有:

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

如果我没有在第一类中设置 Id(通过调用 class1.setId()),结果是来自 Dozer 的 NullPointerException。我知道这是正确的,因为 get("id") 将为空。

我当然可以通过检查 null 并返回 -1 或 0 或其他什么来解决这个问题。

问题是这会变成运行时错误而不是编译时错误。我更愿意正确解决这个问题。

现在我在Dozer 文档中读到,您可以通过执行 map-null="false" 让它跳过 null,但我无法让它工作......

有什么建议么?

4

1 回答 1

1

我相信问题不在于推土机,而在于您的吸气剂中隐藏的自动拆箱:

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

(Integer)get("id") 被隐式转换为 int,因为您的方法的返回类型是“int”。

这在大多数情况下都有效...除了结果为 null 时,在这种情况下您会收到 NullPointerException,因为 int 可能永远不会为 null。

这导致隐藏的 NullPointerExceptions...更多信息:http ://www.theserverside.com/blogs/thread.tss?thread_id=41731

要解决此问题,您有多种选择:

  • 如果 Class1 和 Class2 实际上可能包含 null id,则您需要修改 getter/setter 以获取/设置整数而不是原始整数。

  • 如果 Class1 和 Class2 都不应包含 null id,并且您认为这是一个类不变量,您可以在 getter/setter 中保留原始 int 类型,并且:

    • 确保 get("id") 永远不会为 null,方法是在构造函数中将其初始化为某个特定值(例如 0),并确保没有任何东西可以将其设置为 null。
    • 或者决定 getId() 如果为 null 则返回默认值,并按照您所说的在 getter 中添加一个 null 检查。
  • 如果 Class1 可能有 null id,但 Class2 可能没有,您应该让 Class1 的 getter 和 setter 使用 Integer 类型而不是 int 原语,并且您应该创建一个推土机 CustomConverter,当源字段为 null 时返回默认值。

问候


[编辑] 这是显示 Dozer 在被要求时确实忽略映射空值的测试代码:

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 回答