Подтвердить что ты не робот

Дозер: Как ограничить глубину отображений?

В настоящее время я использую Dozer для сопоставления объектов Entity с объектами Dto в моем проекте.

Мой вопрос в том, как ограничить уровни или глубину внутренних сопоставлений?

Например, у меня есть объект AccountProfile, который имеет объект List<AccountProfileDetail> как член. Более того, AccountProfileDetail сам имеет объект FinancialTransLimit как член.

Теперь я хочу рассказать картографу, который, например, делает сопоставления только с depth = 2. Таким образом, член FinancialTransLimit не копируется в элемент AccountProfileDetail объекта назначения.

Мне нужно указать глубину , используя API-интерфейс 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;
    }
}

AccountProfileDetail

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

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

Тестовый код с Орикой:

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;
    }
}
4b9b3361

Ответ 1

Я не думаю, что это было возможно в последней версии, которую я использовал (5.5.X). Бульдозер попытается сопоставить объекты от одного до другого, пока он не ударит в конец. Если он найдет круговые отношения, он выкинет исключение. Кроме того, исключение будет выбрано, если два объекта имеют атрибуты разных типов, которые называются одинаковыми. В этом весь смысл использования 3-й партийной библиотеки карт. Однако, если целевой объект не содержит атрибута, который может использоваться при сопоставлении источника, этот атрибут будет просто проигнорирован. То же самое должно теоретически работать, если вы назовете целевые атрибуты по-разному. Вы можете разработать некоторые хаки, используя эти правила.

Я бы посоветовал вам использовать Dozer только в том случае, если у вас есть от 1 до 1 сопоставлений без каких-либо различий в исходных и целевых объектах. Если у вас есть различия или ограничения на то, как вы хотите их сопоставить, напишите свои собственные конвертеры.