我尝试将 DTO 对象映射到 JPA 实体。我的 ParentEntity
中有一个 children
集合。可以通过 addChild()
添加它们。 Mapstruct 通过 CollectionMappingStrategy
( http://mapstruct.org/documentation/dev/reference/html/#collection-mapping-strategies ) 支持使用加法器。
如果我创建新实体,但在添加新子实体之前无法清除更新时的子实体,则效果很好。
Mapstruct 手册说 ( http://mapstruct.org/documentation/dev/reference/html/#updating-bean-instances ):
Collection- or map-typed properties of the target bean to be updated will be cleared and then populated with the values from the corresponding source collection or map.
我错过了什么?我还需要设置其他选项吗? https://github.com/davidfuhr/mapstruct-jpa-child-parent 有一个带有测试用例的完整示例来重现问题。
以下是类(class):
public class ParentEntity {
private String name;
private List<ChildEntity> children = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<ChildEntity> getChildren() {
return children;
}
public void addChild(ChildEntity child) {
children.add(child);
child.setMyParent(this);
}
public void removeChild(ChildEntity child) {
children.remove(child);
child.setMyParent(null);
}
}
public class ChildEntity {
private String name;
private ParentEntity myParent;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ParentEntity getMyParent() {
return myParent;
}
public void setMyParent(ParentEntity myParent) {
this.myParent = myParent;
}
}
public class ParentDto {
private String name;
private List<ChildDto> children;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<ChildDto> getChildren() {
return children;
}
public void setChildren(List<ChildDto> children) {
this.children = children;
}
}
public class ChildDto {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface SourceTargetMapper {
SourceTargetMapper MAPPER = Mappers.getMapper(SourceTargetMapper.class);
ParentEntity toEntity(ParentDto s);
ParentEntity updateEntity(ParentDto s, @MappingTarget ParentEntity e);
@Mapping(target = "myParent", ignore = true)
ChildEntity toEntity(ChildDto s);
}
最佳答案
文档中的文本需要重新措辞。问题是,特别是对于集合来说,在 MapStruct 中没有现成的处理这个问题的好方法。我目前正在为文档编写一些新文本。
考虑这一点(当考虑 MapStruct 通常应该如何更新集合时):
- 如果没有匹配项怎么办:是否应该删除不匹配的元素?
- 是否应该添加不匹配的源元素?
- 匹配的具体构成是什么:等于?哈希码?比较器==0?
- 是否可以有多个匹配项(列表,但也取决于什么被视为匹配项。)
- 应如何对结果集合进行排序?
- 是否应该将新创建的对象添加到持久性上下文中?
- JPA 子女与 parent 的关系如何?
关于后一个,Dali(Eclipse)也生成了remove方法。那么 MapStruct 应该根据上述内容调用这些吗?
此时它的工作原理如下:每当用户需要集合更新方法时,MapStruct 都会生成对元素映射的常规调用(而不是更新调用),因为这是唯一明智的做法。所有其余部分都高度依赖于用例。如果您需要事先清除集合,请使用@BeforeMapping
来清除它。
注意:我刚刚修复了一个问题,该问题还以这种方式处理加法器,而不是您现在收到的模糊错误消息。
如果您想要一种好方法来处理子/父关系并将其与 JPA 集成..请查看 examples 。
关于java - Mapstruct:使用加法器时清除更新集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54881461/