java - java mapstruct 1.3.1忽略双向DTO映射列表中的属性
问题描述
我正在努力解决 MapStruct 的循环依赖问题。由于循环依赖,我一直遇到 StackOverFlow 错误。为了避免它,我只需要排除列表的一个属性。我发现了这一点:https :
//github.com/mapstruct/mapstruct/issues/933使用@Context CycleAvoidingMappingContext
,对我不起作用)。
[编辑]:感谢 MapStruct 聊天,我找到了一种解决方法,我将其添加到EditorMapper
这是我的情况,我猜很常见:我有 2 个 DTO 相互引用:
public class BookDTO {
private Long id;
private String title;
//... other properties
//@JsonManagedReference --> not necessary anymore
private EditorDTO editor;
}
public class EditorDTO {
private Long id;
private String name;
//...other properties
//@JsonBackReference --> not necessary anymore
private List< BookDTO > bookList;
}
而且我需要 MapStruct 能够从 Editor 中的 BookList 中排除属性 Editor,然后避免无限循环。这是我目前拥有的映射器:
@Mapper
public interface BookMapper {
BookMapper INSTANCE = Mappers.getMapper( BookMapper.class );
@Mapping( target = "editor.bookList", ignore = true)
BookDTO toDTO( BookEntity bookEntity );
@Named( "NoEditor" )
@Mapping(target = "editor", ignore = true)
BookDTO toDTONoEditor( BookEntity bookEntity );
List<BookDTO> toDTOList( List<BookEntity> bookEntityList );
@Named( "NoEditor" )
@IterableMapping(qualifiedByName="NoEditor")
List<BookDTO> toDTOListNoEditor( List<BookEntity> bookEntityList );
@Mapping( target = "editor.bookList", ignore = true)
BookEntity toEntity( BookDTO bookDTO );
List<BookEntity> toEntityList( List<BookDTO> bookDTOList );
}
@Mapper(uses = BookMapper.class)
public interface EditorMapper {
EditorMapper INSTANCE = Mappers.getMapper( EditorMapper.class );
@Named( "NoEditor" )
@Mapping(target = "bookList", qualifiedByName = "NoEditor")
EditorDTO toDTO( EditorEntity editorEntity );
@Named( "NoEditor" )
@IterableMapping(qualifiedByName="NoEditor")
List<EditorDTO> toDTOList( List< EditorEntity > editorEntityList );
EditorEntity toEntity( EditorDTO editorDTO );
List<EditorEntity> toEntityList( List< EditorDTO > editorDTOList );
}
[编辑]:它现在可以工作,但不是 100% 干净(请参阅我发布的答案以获取更多详细信息)
我也在mappers中尝试过这种方法,但对我的pb没有任何影响。
BookDTO toDTO( BookEntity bookEntity, @Context CycleAvoidingMappingContext context );
有谁知道我做错了什么?多谢!:)
解决方案
[编辑]:我也添加了双向多对多映射的解决方案
感谢https://gitter.im/mapstruct/mapstruct-users#,我已经能够获得解决方案。
[编辑]:我仍然有我没有意识到的错误。现在已在此更新中更正。
我必须: - 将uses
属性添加到EditorMapper
:@Mapper(componentModel = "spring", uses = BookMapper.class)
- 添加替代方法,例如toDTONoEditor
或toDTOListNoEditor
在BookMapper
我忽略该editor
属性的地方。- 将这些替代方法映射到EditorMapper
- 每个循环依赖项都相同
这是解决方案:
预订DTO
public class BookDTO {
private Long id;
private String title;
//... other properties
private EditorDTO editor;
private List< CategoryDTO > categoryList;
}
编辑器DTO
public class EditorDTO {
private Long id;
private String name;
//...other properties
private List< BookDTO > bookList;
}
类别DTO
public class CategoryDTO {
private Long id;
private String category;
private List< BookDTO > bookList;
}
图书映射器
@Mapper(componentModel = "spring", uses = {CategoryMapper.class, EditorMapper.class})
public interface BookMapper {
@Named( "NoBook" )
@Mappings( {
@Mapping(target = "categoryList", qualifiedByName = "NoBook"),
@Mapping( target = "editor.bookList", ignore = true)
} )
BookDTO toDTO( BookEntity bookEntity );
@Named( "NoEditor" )
@Mappings( {
@Mapping(target = "editor", ignore = true),
@Mapping(target = "categoryList", qualifiedByName = "NoBook")
} )
BookDTO toDTONoEditor( BookEntity bookEntity );
@Named( "NoCategory" )
@Mappings( {
@Mapping(target = "categoryList", ignore = true),
@Mapping(target = "editor", qualifiedByName = "NoBook")
} )
BookDTO toDTONoCategory( BookEntity bookEntity );
@Named( "NoBook" )
@IterableMapping(qualifiedByName="NoBook")
List<BookDTO> toDTOList( List<BookEntity> bookEntityList );
@Named( "NoEditor" )
@IterableMapping(qualifiedByName="NoEditor")
List<BookDTO> toDTOListNoEditor( List<BookEntity> bookEntityList );
@Named( "NoCategory" )
@IterableMapping(qualifiedByName="NoCategory")
List<BookDTO> toDTOListNoCategory( List<BookEntity> bookEntityList );
@Named( "NoBook" )
@Mappings( {
@Mapping(target = "categoryList", qualifiedByName = "NoBook"),
@Mapping( target = "editor.bookList", ignore = true)
} )
BookEntity toEntity( BookDTO bookDTO );
@Named( "NoCategory" )
@Mapping(target = "categoryList", ignore = true)
BookEntity toEntityNoCategory( BookDTO bookDTO );
@Named( "NoBook" )
@IterableMapping(qualifiedByName="NoBook")
List<BookEntity> toEntityList( List<BookDTO> bookDTOList );
@Named( "NoCategory" )
@IterableMapping(qualifiedByName="NoCategory")
List<BookEntity> toEntityListNoCategory( List<BookDTO> bookDTOList );
}
编辑器映射器
@Mapper(componentModel = "spring", uses = BookMapper.class)
public interface EditorMapper {
@Named( "NoEditor" )
@Mapping(target = "bookList", qualifiedByName = "NoEditor")
EditorDTO toDTO( EditorEntity editorEntity );
@Named( "NoBook" )
@Mapping(target = "bookList", ignore = true)
EditorDTO toDTONoBook( EditorEntity editorEntity );
@Named( "NoEditor" )
@IterableMapping(qualifiedByName="NoEditor")
List< EditorDTO > toDTOList( List< EditorEntity > editorEntityList );
@Named( "NoBook" )
@IterableMapping(qualifiedByName="NoBook")
List< EditorDTO > toDTOListNoBook( List< EditorEntity > editorEntityList );
@Named( "NoBook" )
@Mapping(target = "bookList", qualifiedByName = "NoBook")
EditorEntity toEntity( EditorDTO editorDTO );
@Named( "NoBook" )
@IterableMapping(qualifiedByName="NoBook")
List< EditorEntity > toEntityList( List< EditorDTO > editorDTOList );
}
类别映射器
@Mapper(componentModel = "spring",uses = BookMapper.class)
public interface CategoryMapper {
@Named( "NoCategory" )
@Mapping(target = "bookList", qualifiedByName = "NoCategory")
CategoryDTO toDTO( CategoryEntity categoryEntity );
@Named( "NoBook" )
@Mapping(target = "bookList", ignore = true)
CategoryDTO toDTONoBook( CategoryEntity categoryEntity );
@Named( "NoCategory" )
@IterableMapping(qualifiedByName="NoCategory")
List<CategoryDTO> toDTOList( List< CategoryEntity > categoryEntityList );
@Named( "NoBook" )
@IterableMapping(qualifiedByName="NoBook")
List<CategoryDTO> toDTOListNoBook( List< CategoryEntity > categoryEntityList );
@Named( "NoCategory" )
@Mapping(target = "bookList", qualifiedByName = "NoCategory")
CategoryEntity toEntity( CategoryDTO categoryDTO );
@Named( "NoBook" )
@Mapping(target = "bookList", ignore = true)
CategoryEntity toEntityNoBook( CategoryDTO categoryDTO );
@Named( "NoCategory" )
@IterableMapping(qualifiedByName="NoCategory")
List<CategoryEntity> toEntityList( List< CategoryDTO > categoryDTOList );
@Named( "NoBook" )
@IterableMapping(qualifiedByName="NoBook")
List<CategoryEntity> toEntityListNoBook( List< CategoryDTO > categoryDTOList );
}
这样,循环依赖在无限循环之前就被打破了。但是,它是 99% 令人满意的,因为Editor
和Book
对象不是完全干净的。Editor
包含 bookList,嗯。但是其中的每本书bookList
仍然包含一个空editor
字段。反之亦然Book
。但这似乎是一个 De/Serialization 问题,而不是 MapStruct 问题。这是结果的Json
编辑
{
"id": 1,
"name": "Folio",
"coordinates": null,
"bookList": [
{
"id": 1,
"title": "Le cycle de Fondation, I : Fondation",
"categoryList": [
{
"id": 5,
"category": "LITERATURE&FICTION"
}
],
"language": "French",
"isbn": 2070360539,
"publicationDate": null,
"numberOfPages": 416,
"authorList": [],
"libraryList": [
{
"id": 2,
"name": "Library2",
"coordinates": null
},
{
"id": 1,
"name": "Library1",
"coordinates": null
}
],
"editor": null
}
]
}
书
{
"id": 1,
"title": "Le cycle de Fondation, I : Fondation",
"categoryList": [
{
"id": 5,
"category": "LITERATURE&FICTION",
"bookList": null
}
],
"language": "French",
"isbn": 2070360539,
"publicationDate": null,
"numberOfPages": 416,
"authorList": [],
"libraryList": [
{
"id": 2,
"name": "Library2",
"coordinates": null
},
{
"id": 1,
"name": "Library1",
"coordinates": null
}
],
"editor": {
"id": 1,
"name": "Folio",
"coordinates": null,
"bookList": null
}
}
类别
{
"id": 1,
"category": "CHILDREN",
"bookList": [
{
"id": 5,
"title": "Le petit prince",
"categoryList": null,
"language": "French",
"isbn": 9782070612758,
"publicationDate": null,
"numberOfPages": 120,
"authorList": [],
"libraryList": [
{
"id": 2,
"name": "Library2",
"coordinates": null
},
{
"id": 1,
"name": "Library1",
"coordinates": null
}
],
"editor": null
}
]
}
希望这有帮助:)
推荐阅读
- bluetooth-lowenergy - 通过网络蓝牙做广告
- c - 使用 strcmp 取消引用指向不完整类型错误的指针
- javascript - javascript引擎中的回调是如何实现的?(不是关于如何使用回调)
- javascript - 如何将提取数据与从不同提取调用的图像匹配?
- sql-server - 如何返回具有最小和最大列值的行
- java - 从 Json 对象中提取数组
- javascript - 写入 Google 表格(Chrome 扩展程序)
- tensorflow - 是否有可能将标签位置从上到下移动?
- amazon-redshift - 哪个 postgres 模式和关系列出了与数据库的连接?
- vba - 访问 VBA:在表单上打开设置标签