英文:
ModelMapper mapping the wrong id
问题
我在将DTO映射到具有嵌套对象的实体时遇到了问题。
基本上,“DayEntry”包含许多“SingleEntry”,每个“SingleEntry”都有一个“Category”。
以下是我的实体:
@Entity
public @Data class SingleEntry {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id ;
private float value ;
private boolean isInEntry= true;
@ManyToOne
@JoinColumn(nullable=false)
private Category category;
@ManyToOne
@JoinColumn(nullable=false)
private DayEntry dayEntry;
}
@Entity
public @Data class Category {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;
@Column(unique = true)
private String name;
private String color ="cc8282";
@OneToMany(mappedBy = "category")
//@JsonManagedReference
private List<SingleEntry> singleEntryList;
}
@Entity
public @Data class DayEntry {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private LocalDate date;
@OneToMany(mappedBy = "dayEntry", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<SingleEntry> singleEntryList;
}
这是我使用的DTO:
public @Data class SingleEntryForCreationDto {
private float value ;
private boolean isInEntry;
private int categoryId;
private int dayEntryId;
}
我试图创建一个新的“SingleEntry”,这就是为什么DTO中没有“id”,因为它会自动生成,但当我使用ModelMapper时:
modelMapper.map(singleEntryForCreationDto, SingleEntry.class)
它将“categoryId”映射到实体“SingleEntry”的“id”字段,就像你在日志示例中看到的那样:
********* dto == SingleEntryForCreationDto(value=50.0, isInEntry=false, categoryId=2, dayEntryId=1)
********* mapped dto == SingleEntry(id=2, value=50.0, isInEntry=false, category=Category(id=2, name=null, color=cc8282, singleEntryList=null), dayEntry=DayEntry(id=1, date=null, singleEntryList=null))
我查看了ModelMapper的文档,并尝试更改命名约定和转换配置,但没有帮助。我一定是遗漏了什么,而且我肯定不太理解ModelMapper的工作原理,因为我无法自己解决这个问题。
编辑:
我仍然不明白为什么它将categoryId(SingleEntryForCreationDto)映射到id(SingleEntry)。我暂时通过以下方式解决了这个问题:
modelMapper.typeMap(SingleEntryForCreationDto.class,SingleEntry.class).addMappings(mapper -> mapper.skip(SingleEntry::setId));
英文:
I have an issue while mapping a dto to an entity with nested objects.
Basically a "DayEntry" cotains many "SingleEntry" and each "SingleEntry" has a "Category".
Here are my entities :
@Entity
public @Data class SingleEntry {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id ;
private float value ;
private boolean isInEntry= true;
@ManyToOne
@JoinColumn(nullable=false)
private Category category;
@ManyToOne
@JoinColumn(nullable=false)
private DayEntry dayEntry;
}
@Entity
public @Data class Category {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;
@Column(unique = true)
private String name;
private String color ="cc8282";
@OneToMany(mappedBy = "category")
//@JsonManagedReference
private List<SingleEntry> singleEntryList;
}
@Entity
public @Data class DayEntry {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private LocalDate date;
@OneToMany(mappedBy = "dayEntry", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<SingleEntry> singleEntryList;
}
And this is the Dto i'm using :
public @Data class SingleEntryForCreationDto {
private float value ;
private boolean isInEntry;
private int categoryId;
private int dayEntryId;
}
I'm trying to create a new "SingleEntity" so that's why i have no "id" in the dto as it's going to be generated, but when i use model mapper :
modelMapper.map(singleEntryForCreationDto, SingleEntry.class)
it maps the "categoryId" to the "id" field of the entity "SingleEntry" like you can see in this example of logs :
********* dto == SingleEntryForCreationDto(value=50.0, isInEntry=false, categoryId=2, dayEntryId=1)
********* mapped dto == SingleEntry(id=2, value=50.0, isInEntry=false, category=Category(id=2, name=null, color=cc8282, singleEntryList=null), dayEntry=DayEntry(id=1, date=null, singleEntryList=null))
I looked at the documentation of Modelmapper and tried to change the NamingConventions and Transormation configuration but it didn't help. I must be missing something and i surely don't understand how Modelmapper really works as i couldn't fix it on my own.
I'd appreciate any help or suggestions.
******EDIT :
I still don't understand why it mapped categoryId (SingleEntryForCreationDto) to id (SingleEntry). I resolved it this way for now
modelMapper.typeMap(SingleEntryForCreationDto.class,SingleEntry.class).addMappings(mapper -> mapper.skip(SingleEntry::setId));
答案1
得分: 2
我找不到为什么您的配置将SingleEntry的id设置为2,但我认为您最好使用显式映射。
您可以使用PropertyMap配置跳过目标中的任何字段。
显式映射示例:不跳过,而是使用map()
https://github.com/modelmapper/modelmapper/blob/master/examples/src/main/java/org/modelmapper/flattening/example2/FlatteningExample2.java
您可以在此链接中的“Skipping Properties”部分找到如何使用skip()的方法。
http://modelmapper.org/javadoc/org/modelmapper/PropertyMap.html
英文:
I couldn't find why your configuration set the value of SingleEntry's id 2, but I think you'd better use explicit mapping.
You can skip any field in destination with PropertyMap configuration.
Explicit mappings example: no skipping but map()
https://github.com/modelmapper/modelmapper/blob/master/examples/src/main/java/org/modelmapper/flattening/example2/FlatteningExample2.java
You can find how to use skip() in 'Skipping Properties' section in this link.
http://modelmapper.org/javadoc/org/modelmapper/PropertyMap.html
答案2
得分: 0
你需要将匹配策略设置为STRICT
。
http://modelmapper.org/user-manual/configuration/#matching-strategies
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.STRICT);
return modelMapper;
}
英文:
You need to set Matching Strategies to STRICT
http://modelmapper.org/user-manual/configuration/#matching-strategies
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.STRICT);
return modelMapper;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论