ModelMapper映射了错误的ID。

huangapple go评论92阅读模式
英文:

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 =&quot;cc8282&quot;;
    @OneToMany(mappedBy = &quot;category&quot;)
    //@JsonManagedReference
    private List&lt;SingleEntry&gt; singleEntryList;
}
@Entity
public @Data class DayEntry {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;
    @Column(nullable = false)
    private LocalDate date;
    @OneToMany(mappedBy = &quot;dayEntry&quot;, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List&lt;SingleEntry&gt; 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 -&gt; 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;
    }

huangapple
  • 本文由 发表于 2020年9月26日 21:34:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/64078284.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定