java - Dozer:如何限制映射的深度?

标签 java dozer object-object-mapping

我目前正在使用 Dozer 进行映射 Entity反对 Dto我项目中的对象。

我的问题是如何限制内部映射的层次或深度?

例如我有一个 AccountProfile具有 List<AccountProfileDetail> 的实体实体作为成员。此外AccountProfileDetail本身有一个 FinancialTransLimit实体作为成员。

现在我想告诉映射器,例如只用 depth = 2 做映射。 .所以 FinancialTransLimit成员不会被复制到 AccountProfileDetail目标对象的成员。

我需要使用编程 API 指定深度,而不是在 xml 中。但是,我也没有在 xml 配置中找到它。

我也试过 Orika,但我在 Orika 中也找不到这样的功能!

以下两个代码(用于使用 Dozer 和 Orika 作为替代进行测试)都可以正常工作并进行深度复制。 我需要限制其中至少一个的深度

有人可以帮我解决这个问题吗?

非常感谢!

示例代码:

账户资料

//My Entities:
import java.util.List;

public class AccountProfile{

    private Long id;
    private String name;
    private List<AccountProfileDetail> accountProfileDetails;

    public AccountProfile() {
    }

    public Long getId() {
        return this.id;
    }

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

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<AccountProfileDetail> getAccountProfileDetails() {
        return this.accountProfileDetails;
    }

    public void setAccountProfileDetails(List<AccountProfileDetail> accountProfileDetails) {
        this.accountProfileDetails = accountProfileDetails;
    }
}

账户资料详情

import java.math.BigDecimal;

public class AccountProfileDetail {

    private Long id;
    private BigDecimal accountMinBalance;
    private AccountProfile accountProfile;
    private FinancialTransLimit financialTransLimit;

    public AccountProfileDetail() {
    }

    public Long getId() {
        return this.id;
    }

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

    public BigDecimal getAccountMinBalance() {
        return this.accountMinBalance;
    }

    public void setAccountMinBalance(BigDecimal accountMinBalance) {
        this.accountMinBalance = accountMinBalance;
    }

    public AccountProfile getAccountProfile() {
        return this.accountProfile;
    }

    public void setAccountProfile(AccountProfile accountProfile) {
        this.accountProfile = accountProfile;
    }

    public FinancialTransLimit getFinancialTransLimit() {
        return this.financialTransLimit;
    }

    public void setFinancialTransLimit(FinancialTransLimit financialTransLimit) {
        this.financialTransLimit = financialTransLimit;
    }
}

金融交易限制

public class FinancialTransLimit{

    private Long id;
    private String limitCode;

    public FinancialTransLimit() {
    }

    public Long getId() {
        return this.id;
    }

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

    public String getLimitCode() {
        return this.limitCode;
    }

    public void setLimitCode(String limitCode) {
        this.limitCode = limitCode;
    }
}

AccountProfileDto

// My Dtos:
import java.util.List;

public class AccountProfileDto{
    private Long id;
    private String name;
    private List<AccountProfileDetailDto> accountProfileDetails;

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public List<AccountProfileDetailDto> getAccountProfileDetails() {
        return accountProfileDetails;
    }

    public void setAccountProfileDetails(List<AccountProfileDetailDto> accountProfileDetails) {
        this.accountProfileDetails = accountProfileDetails;
    }
}

AccountProfileDetailDto

import java.math.BigDecimal;

public class AccountProfileDetailDto {

    private Long id;
    private BigDecimal accountMinBalance;
    private AccountProfileDto accountProfile;
    private FinancialTransLimitDto financialTransLimit;

    public Long getId() {
        return id;
    }

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

    public BigDecimal getAccountMinBalance() {
        return accountMinBalance;
    }

    public void setAccountMinBalance(BigDecimal accountMinBalance) {
        this.accountMinBalance = accountMinBalance;
    }

    public AccountProfileDto getAccountProfile() {
        return accountProfile;
    }

    public void setAccountProfile(AccountProfileDto accountProfile) {
        this.accountProfile = accountProfile;
    }

    public FinancialTransLimitDto getFinancialTransLimit() {
        return financialTransLimit;
    }

    public void setFinancialTransLimit(FinancialTransLimitDto financialTransLimit) {
        this.financialTransLimit = financialTransLimit;
    }
}

FinancialTransLimitDto

public class FinancialTransLimitDto {
    private Long id;
    private String limitCode;

    public Long getId() {
        return id;
    }

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

    public String getLimitCode() {
        return limitCode;
    }

    public void setLimitCode(String limitCode) {
        this.limitCode = limitCode;
    }
}

现在是Dozer的测试用例代码:

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;


public class TestDozer {

    public static void main(String[] args) {

        List<AccountProfile> profiles = createList();

        Mapper mapper = new DozerBeanMapper();

        List<AccountProfileDto> profileDtos = new ArrayList<AccountProfileDto>(); 

        for (AccountProfile entity: profiles) {
            AccountProfileDto dto = new AccountProfileDto();
            mapper.map(entity, dto);
            profileDtos.add(dto);
        }

        System.out.println(Arrays.deepToString(profileDtos.toArray()));
    }

    private static List<AccountProfile> createList(){
        List<AccountProfile> accountProfiles = new ArrayList<AccountProfile>();

        AccountProfile ap1 = new AccountProfile();
        ap1.setId(new Long(1000));
        ap1.setName("profile1");

        FinancialTransLimit ftlt1 = new FinancialTransLimit();
        ftlt1.setId(new Long(3000));
        ftlt1.setLimitCode("L1");

        AccountProfileDetail apd1 = new AccountProfileDetail();
        apd1.setId(new Long(2000));
        apd1.setAccountProfile(ap1);
        apd1.setAccountMinBalance(new BigDecimal(100000));
        apd1.setFinancialTransLimit(ftlt1);

        List<AccountProfileDetail> apds1 = new ArrayList<AccountProfileDetail>();
        apds1.add(apd1);
        ap1.setAccountProfileDetails(apds1);

        accountProfiles.add(ap1);
        //
        AccountProfile ap2 = new AccountProfile();
        ap2.setId(new Long(1001));
        ap2.setName("profile2");

        FinancialTransLimit ftlt2 = new FinancialTransLimit();
        ftlt2.setId(new Long(3001));
        ftlt2.setLimitCode("L2");

        AccountProfileDetail apd2 = new AccountProfileDetail();
        apd2.setId(new Long(2001));
        apd2.setAccountProfile(ap2);
        apd2.setAccountMinBalance(new BigDecimal(200000));
        apd2.setFinancialTransLimit(ftlt2);

        List<AccountProfileDetail> apds2 = new ArrayList<AccountProfileDetail>();
        apds2.add(apd2);
        ap2.setAccountProfileDetails(apds2);

        accountProfiles.add(ap2);
        //
        return accountProfiles;
    }
}

使用 Orika 测试代码:

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import ma.glasnost.orika.BoundMapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;

public class TestOrika {

    public static void main(String[] args) {

        List<AccountProfile> profiles = createList();

        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        BoundMapperFacade<AccountProfile, AccountProfileDto> mapper = mapperFactory.getMapperFacade(AccountProfile.class, AccountProfileDto.class);

        List<AccountProfileDto> profileDtos = new ArrayList<AccountProfileDto>(); 

        for (AccountProfile entity: profiles) {
            AccountProfileDto dto = new AccountProfileDto();
            mapper.map(entity, dto);
            profileDtos.add(dto);
        }

        System.out.println(Arrays.deepToString(profileDtos.toArray()));
    }

    private static List<AccountProfile> createList(){
        List<AccountProfile> accountProfiles = new ArrayList<AccountProfile>();

        AccountProfile ap1 = new AccountProfile();
        ap1.setId(new Long(1000));
        ap1.setName("profile1");

        FinancialTransLimit ftlt1 = new FinancialTransLimit();
        ftlt1.setId(new Long(3000));
        ftlt1.setLimitCode("L1");

        AccountProfileDetail apd1 = new AccountProfileDetail();
        apd1.setId(new Long(2000));
        apd1.setAccountProfile(ap1);
        apd1.setAccountMinBalance(new BigDecimal(100000));
        apd1.setFinancialTransLimit(ftlt1);

        List<AccountProfileDetail> apds1 = new ArrayList<AccountProfileDetail>();
        apds1.add(apd1);
        ap1.setAccountProfileDetails(apds1);

        accountProfiles.add(ap1);

        //

        AccountProfile ap2 = new AccountProfile();
        ap2.setId(new Long(1001));
        ap2.setName("profile2");

        FinancialTransLimit ftlt2 = new FinancialTransLimit();
        ftlt2.setId(new Long(3001));
        ftlt2.setLimitCode("L2");

        AccountProfileDetail apd2 = new AccountProfileDetail();
        apd2.setId(new Long(2001));
        apd2.setAccountProfile(ap2);
        apd2.setAccountMinBalance(new BigDecimal(200000));
        apd2.setFinancialTransLimit(ftlt2);

        List<AccountProfileDetail> apds2 = new ArrayList<AccountProfileDetail>();
        apds2.add(apd2);
        ap2.setAccountProfileDetails(apds2);

        accountProfiles.add(ap2);

        //

        return accountProfiles;
    }
}

最佳答案

我认为在我使用的上一个版本 (5.5.X) 中这是不可能的。推土机将尝试将对象从一个对象映射到另一个对象,直到他到达终点。如果他发现有循环关系,就会抛出异常。此外,如果两个对象具有名称相同的不同类型的属性,也会抛出异常。这就是使用第 3 方映射器库的全部意义所在。 但是,如果目标对象不包含可以在源映射期间使用的属性,则该属性将被忽略。如果您以不同的方式命名目标属性,理论上应该同样有效。您可以使用这些规则解决一些问题。

我建议您仅在源对象和目标对象没有差异的一对一映射时才坚持使用 Dozer。如果您对映射方式有不同或限制,请编写自己的转换器。

关于java - Dozer:如何限制映射的深度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33498883/

相关文章:

用于有条件地删除空格的 Java 模式正则表达式

java - 使用 Java、Dozer 和 Hibernate 将 DTO 映射和更新到数据库

java - 简单测试中的 NoClassDefFoundError

java - 为什么 addNode() 方法返回编译错误 "The method...in type...is not applicable for the arguments...",以及如何修复它?

java - 将文本从文件复制到 HttpServletResponse 的最快方法

java - AJAX 框架实现的最佳实践

java - Dozer Mapper 未映射组成的嵌套字段

java - 如何使用推土机映射将字符串常量发送到字段值?

java - Dozer 映射参数计数不匹配的两个类