MapStruct 忽略对象内列表内的 属性
MapStruct Ignore a property inside a list inside a Object
我有这个:
@Entity
public class Upgrade {
...
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "UPGRADE_PROJECT", joinColumns = @JoinColumn(name = "UPGRADE_ID"),
inverseJoinColumns = @JoinColumn(name = "PROJECT_ID"))
private List<Project> projects = new ArrayList<>();...}
和
public class Project {
@ManyToMany(mappedBy = "projects")
private List<Upgrade> upgrades = new ArrayList<>();
DTO 也类似于实体。
@Mapper(componentModel = "spring", uses = {VersionMapper.class, ProjectMapper.class,
YearMonthMapper.class})
public interface UpgradeMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MMMM yyyy")
UpgradeDTO upgradeToUpgradeDto(Upgrade upgrade, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MM-yyyy")
Upgrade upgradeDtoToUpgrade(UpgradeDTO upgradeDTO, @Context CycleAvoidingMappingContext context);
}
和
@Mapper(componentModel = "spring", uses = {UpgradeMapper.class, YearMonthMapper.class})
public interface ProjectMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MMMM yyyy")
@Mapping(target = "toDate", dateFormat = "MMMM yyyy")
ProjectDTO projectToProjectDto(Project project, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MM-yyyy")
@Mapping(target = "toDate", dateFormat = "MM-yyyy")
Project projectDtoToProject(ProjectDTO projectDTO, @Context CycleAvoidingMappingContext context);
}
我像这样使用映射器:
CycleAvoidingMappingContext cycleAvoidingMappingContext = new CycleAvoidingMappingContext();
Upgrade upgrade = upgradeMapper.upgradeDtoToUpgrade(upgradeDTO, cycleAvoidingMappingContext);
upgrade = setupAndSave(versionId, upgrade);
return upgradeMapper.upgradeToUpgradeDto(upgrade, cycleAvoidingMappingContext);
我在创建升级时得到这个结果:
{
"id": 1804,
"version": {
"id": 2007,
"technology": {
...
},
..
},
...
"projects": [
{
"id": 603,
...
THIS SHOULD BE IGNORED
"upgrades": [
{
"id": 1703,
"projects": [
{
"id": 603,
"upgrades": [
1703,
{
"id": 1704,
"projects": [
AND GOES ON AND ON
],
},
..,
..
],
..
},
{
"id": 604,
"upgrades": [
1703,
1704,
1803,
1804
],
..
}
],
..
},
1704,
1803,
1804
],
...
},
{
"id": 604,
"upgrades": [
1703,
1704,
1803,
1804
],
..
}
],
..
}
我希望能够做这样的事情
public interface UpgradeMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MMMM yyyy")
@Mapping(target = "projects.upgrades", ignore = true)
UpgradeDTO upgradeToUpgradeDto(Upgrade upgrade, @Context CycleAvoidingMappingContext context);
但它不会工作,因为 projects
是一个列表而不是一个实体。
我目前的修复是:
@Mapper(componentModel = "spring", uses = {UpgradeMapper.class, YearMonthMapper.class})
public interface ProjectMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MMMM yyyy")
@Mapping(target = "toDate", dateFormat = "MMMM yyyy")
@Mapping(target = "upgrades", ignore = true)
ProjectDTO projectToProjectDto(Project project, @Context CycleAvoidingMappingContext context);
所以当我从数据库中获取项目实体并获取 DTO 时,DTO upgrades
为空。
我有办法在不损害关系另一方的情况下实现我的目标吗?
项目
{
"id": 603,
"upgrades": [],
"createdAt": "10/June/2020 at 14:58:47"
}
升级(这是期望的行为)
{
"id": 1804,
"version": {
"id": 2007,
},
..
"projects": [
{
"id": 603,
..
"upgrades": [],
"createdAt": "10/June/2020 at 14:58:47"
},
{
"id": 604,
..
"upgrades": [],
"createdAt": "10/June/2020 at 14:59:59"
}
],
"createdAt": "10/June/2020 at 15:59:52"
}
编辑
根据 Filip 建议现在映射器看起来像这样:
@Mapper(componentModel = "spring", uses = {UpgradeMapper.class, YearMonthMapper.class})
public interface ProjectMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MMMM yyyy")
@Mapping(target = "toDate", dateFormat = "MMMM yyyy")
ProjectDTO projectToProjectDto(Project project, @Context CycleAvoidingMappingContext context);
@Mapping(target = "upgrades", ignore = true)
@InheritConfiguration
@Named("withoutUpgrades")
ProjectDTO projectToProjectDtoWithoutUpgrades(Project project, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MM-yyyy")
@Mapping(target = "toDate", dateFormat = "MM-yyyy")
Project projectDtoToProject(ProjectDTO projectDTO, @Context CycleAvoidingMappingContext context);
}
和
@Mapper(componentModel = "spring", uses = {VersionMapper.class, ProjectMapper.class,
YearMonthMapper.class})
public interface UpgradeMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MMMM yyyy")
@Mapping(target = "projects", qualifiedByName = "withoutUpgrades")
UpgradeDTO upgradeToUpgradeDto(Upgrade upgrade, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MM-yyyy")
Upgrade upgradeDtoToUpgrade(UpgradeDTO upgradeDTO, @Context CycleAvoidingMappingContext context);
}
它仍然不起作用,它仍然使用 projectToProjectDto
而不是 projectToProjectDtoWithoutUpgrades
。怎么了?
您可以使用限定符忽略映射。
例如
@Mapper(componentModel = "spring", uses = {UpgradeMapper.class, YearMonthMapper.class})
public interface ProjectMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MMMM yyyy")
@Mapping(target = "toDate", dateFormat = "MMMM yyyy")
ProjectDTO projectToProjectDto(Project project, @Context CycleAvoidingMappingContext context);
@Mapping(target = "upgrades", ignore = "true"
@InheritConfiguration
@Named("withoutUpgrades")
ProjectDTO projectToProjectDtoWithoutUpgrades(Project project, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MM-yyyy")
@Mapping(target = "toDate", dateFormat = "MM-yyyy")
Project projectDtoToProject(ProjectDTO projectDTO, @Context CycleAvoidingMappingContext context);
}
@Mapper(componentModel = "spring", uses = {VersionMapper.class, ProjectMapper.class,
YearMonthMapper.class})
public interface UpgradeMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MMMM yyyy")
@Mapping(target = "projects", qualifiedByName = "withoutUpgrades")
UpgradeDTO upgradeToUpgradeDto(Upgrade upgrade, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MM-yyyy")
Upgrade upgradeDtoToUpgrade(UpgradeDTO upgradeDTO, @Context CycleAvoidingMappingContext context);
}
这意味着当升级中 projects
的映射完成后,它将使用未经 withoutUpgrades
限定的映射来映射项目。
我有这个:
@Entity
public class Upgrade {
...
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "UPGRADE_PROJECT", joinColumns = @JoinColumn(name = "UPGRADE_ID"),
inverseJoinColumns = @JoinColumn(name = "PROJECT_ID"))
private List<Project> projects = new ArrayList<>();...}
和
public class Project {
@ManyToMany(mappedBy = "projects")
private List<Upgrade> upgrades = new ArrayList<>();
DTO 也类似于实体。
@Mapper(componentModel = "spring", uses = {VersionMapper.class, ProjectMapper.class,
YearMonthMapper.class})
public interface UpgradeMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MMMM yyyy")
UpgradeDTO upgradeToUpgradeDto(Upgrade upgrade, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MM-yyyy")
Upgrade upgradeDtoToUpgrade(UpgradeDTO upgradeDTO, @Context CycleAvoidingMappingContext context);
}
和
@Mapper(componentModel = "spring", uses = {UpgradeMapper.class, YearMonthMapper.class})
public interface ProjectMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MMMM yyyy")
@Mapping(target = "toDate", dateFormat = "MMMM yyyy")
ProjectDTO projectToProjectDto(Project project, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MM-yyyy")
@Mapping(target = "toDate", dateFormat = "MM-yyyy")
Project projectDtoToProject(ProjectDTO projectDTO, @Context CycleAvoidingMappingContext context);
}
我像这样使用映射器:
CycleAvoidingMappingContext cycleAvoidingMappingContext = new CycleAvoidingMappingContext();
Upgrade upgrade = upgradeMapper.upgradeDtoToUpgrade(upgradeDTO, cycleAvoidingMappingContext);
upgrade = setupAndSave(versionId, upgrade);
return upgradeMapper.upgradeToUpgradeDto(upgrade, cycleAvoidingMappingContext);
我在创建升级时得到这个结果:
{
"id": 1804,
"version": {
"id": 2007,
"technology": {
...
},
..
},
...
"projects": [
{
"id": 603,
...
THIS SHOULD BE IGNORED
"upgrades": [
{
"id": 1703,
"projects": [
{
"id": 603,
"upgrades": [
1703,
{
"id": 1704,
"projects": [
AND GOES ON AND ON
],
},
..,
..
],
..
},
{
"id": 604,
"upgrades": [
1703,
1704,
1803,
1804
],
..
}
],
..
},
1704,
1803,
1804
],
...
},
{
"id": 604,
"upgrades": [
1703,
1704,
1803,
1804
],
..
}
],
..
}
我希望能够做这样的事情
public interface UpgradeMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MMMM yyyy")
@Mapping(target = "projects.upgrades", ignore = true)
UpgradeDTO upgradeToUpgradeDto(Upgrade upgrade, @Context CycleAvoidingMappingContext context);
但它不会工作,因为 projects
是一个列表而不是一个实体。
我目前的修复是:
@Mapper(componentModel = "spring", uses = {UpgradeMapper.class, YearMonthMapper.class})
public interface ProjectMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MMMM yyyy")
@Mapping(target = "toDate", dateFormat = "MMMM yyyy")
@Mapping(target = "upgrades", ignore = true)
ProjectDTO projectToProjectDto(Project project, @Context CycleAvoidingMappingContext context);
所以当我从数据库中获取项目实体并获取 DTO 时,DTO upgrades
为空。
我有办法在不损害关系另一方的情况下实现我的目标吗?
项目
{
"id": 603,
"upgrades": [],
"createdAt": "10/June/2020 at 14:58:47"
}
升级(这是期望的行为)
{
"id": 1804,
"version": {
"id": 2007,
},
..
"projects": [
{
"id": 603,
..
"upgrades": [],
"createdAt": "10/June/2020 at 14:58:47"
},
{
"id": 604,
..
"upgrades": [],
"createdAt": "10/June/2020 at 14:59:59"
}
],
"createdAt": "10/June/2020 at 15:59:52"
}
编辑
根据 Filip 建议现在映射器看起来像这样:
@Mapper(componentModel = "spring", uses = {UpgradeMapper.class, YearMonthMapper.class})
public interface ProjectMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MMMM yyyy")
@Mapping(target = "toDate", dateFormat = "MMMM yyyy")
ProjectDTO projectToProjectDto(Project project, @Context CycleAvoidingMappingContext context);
@Mapping(target = "upgrades", ignore = true)
@InheritConfiguration
@Named("withoutUpgrades")
ProjectDTO projectToProjectDtoWithoutUpgrades(Project project, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MM-yyyy")
@Mapping(target = "toDate", dateFormat = "MM-yyyy")
Project projectDtoToProject(ProjectDTO projectDTO, @Context CycleAvoidingMappingContext context);
}
和
@Mapper(componentModel = "spring", uses = {VersionMapper.class, ProjectMapper.class,
YearMonthMapper.class})
public interface UpgradeMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MMMM yyyy")
@Mapping(target = "projects", qualifiedByName = "withoutUpgrades")
UpgradeDTO upgradeToUpgradeDto(Upgrade upgrade, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MM-yyyy")
Upgrade upgradeDtoToUpgrade(UpgradeDTO upgradeDTO, @Context CycleAvoidingMappingContext context);
}
它仍然不起作用,它仍然使用 projectToProjectDto
而不是 projectToProjectDtoWithoutUpgrades
。怎么了?
您可以使用限定符忽略映射。
例如
@Mapper(componentModel = "spring", uses = {UpgradeMapper.class, YearMonthMapper.class})
public interface ProjectMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MMMM yyyy")
@Mapping(target = "toDate", dateFormat = "MMMM yyyy")
ProjectDTO projectToProjectDto(Project project, @Context CycleAvoidingMappingContext context);
@Mapping(target = "upgrades", ignore = "true"
@InheritConfiguration
@Named("withoutUpgrades")
ProjectDTO projectToProjectDtoWithoutUpgrades(Project project, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "fromDate", dateFormat = "MM-yyyy")
@Mapping(target = "toDate", dateFormat = "MM-yyyy")
Project projectDtoToProject(ProjectDTO projectDTO, @Context CycleAvoidingMappingContext context);
}
@Mapper(componentModel = "spring", uses = {VersionMapper.class, ProjectMapper.class,
YearMonthMapper.class})
public interface UpgradeMapper {
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MMMM yyyy")
@Mapping(target = "projects", qualifiedByName = "withoutUpgrades")
UpgradeDTO upgradeToUpgradeDto(Upgrade upgrade, @Context CycleAvoidingMappingContext context);
@Mapping(target = "createdAt", dateFormat = "dd/MMMM/yyyy [ 'at' HH:mm:ss]")
@Mapping(target = "acquired", dateFormat = "MM-yyyy")
Upgrade upgradeDtoToUpgrade(UpgradeDTO upgradeDTO, @Context CycleAvoidingMappingContext context);
}
这意味着当升级中 projects
的映射完成后,它将使用未经 withoutUpgrades
限定的映射来映射项目。