Dozer: Как ограничить глубину отображений?
В настоящее время я использую 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;
}
}
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;
}
}
Тестовый код с 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;
}
}
1 ответ
Я не думаю, что это было возможно в последней версии, которую я использовал (5.5.X). Dozer будет пытаться сопоставлять объекты от одного к другому, пока он не достигнет конца. Если он найдет круговые отношения, он выдаст исключение. Также будет сгенерировано исключение, если два объекта имеют атрибуты разных типов с одинаковыми именами. В этом весь смысл использования библиотеки сторонних картографов. Однако, если целевой объект не содержит атрибута, который можно использовать во время сопоставления источника, этот атрибут будет просто проигнорирован. То же самое теоретически должно работать, если вы называете атрибуты цели по-разному. Вы можете отработать некоторые хаки, используя эти правила.
Я бы посоветовал вам придерживаться Dozer только в том случае, если у вас есть сопоставления 1 к 1 без разницы в исходных и целевых объектах. Если у вас есть различия или ограничения в том, как вы хотите отобразить это, напишите свои собственные конвертеры.