使用Jackson代替DTO在POST映射中?

huangapple 未分类评论43阅读模式
英文:

using jackson instead of DTO in POST mapping?

问题

我有以下的一对多关系:

public class Product {
    @Id
    @SequenceGenerator(name = "product_id_seq", sequenceName = "product_id_seq")
    @GeneratedValue(strategy= GenerationType.SEQUENCE, generator = "product_id_seq")
    private Long pid; // 为了处理 Hibernate 的 bug,将其初始化为一个随机值

    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "manufacturer", referencedColumnName = "id")
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    @JsonIdentityReference(alwaysAsId = true)
    private Manufacturer manufacturer;

    private String name;
    // ......更多的数据成员...
}

以及制造商:

public class Manufacturer {
    @Id
    @SequenceGenerator(name = "manufacturer_id_seq", sequenceName = "manufacturer_id_seq")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "manufacturer_id_seq")
    private Long id;
    private String name;
    private String country;
    @OneToMany(mappedBy = "manufacturer", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Product> products;
}

我的 POST 请求主体包含以下的 JSON 数据:

{
    "name": "chocolate",
    "manufacturer": 2
}

我目前在使用 DTO 和映射函数将 ProductCreationDTO 映射到 Product

public class ProductCreationDTO {
    private String name;
    private Long manufacturer;
}

private Product mapProductCreationDTOtoProduct(ProductCreationDTO pcd) {
    Product p = modelMapper.map(pcd, Product.class); // 将字段映射到同名的字段(如 manufacturer)
    Optional<Manufacturer> o = manufacturerService.getManufacturer(pcd.getManufacturer());
    o.ifPresent(m -> p.setManufacturer(m));
    return p;
}

我在对象的 GET 调用中通过在 Product 类的制造商对象上添加了以下两个注释来成功进行了这种转换:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = true)

是否有一种使用 Jackson(注释)的方式来将 POST 请求中的 JSON 映射到产品对象(反序列化),就像在 REST 的 GET 调用中发生的一样(序列化)?

英文:

I have the following one to many relationship :

public class Product {
        @Id
        @SequenceGenerator(name = &quot;product_id_seq&quot;, sequenceName = &quot;product_id_seq&quot;)
        @GeneratedValue(strategy= GenerationType.SEQUENCE,generator = &quot;product_id_seq&quot;)
    private Long pid; // initiate it for just a random value in order to hanlde hibernate bug

    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name=&quot;manufacturer&quot;,referencedColumnName = &quot;id&quot;)
    @JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property=&quot;id&quot;)
    @JsonIdentityReference(alwaysAsId=true)
    private Manufacturer manufacturer;

   private String name;
   ......more data members...

and manufacturer :

public class Manufacturer {
    @Id
    @SequenceGenerator(name = &quot;manufacturer_id_seq&quot;, sequenceName = &quot;manufacturer_id_seq&quot;)
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator = &quot;manufacturer_id_seq&quot;)
    private Long id;
    private String name;
    private String country;
    @OneToMany(mappedBy = &quot;manufacturer&quot;,fetch = FetchType.LAZY,cascade = CascadeType.ALL, orphanRemoval = true)
    private List&lt;Product&gt; products;
    
}

my POST body contain the following json :

{
	&quot;name&quot;:&quot;chocolate&quot;,
	&quot;manufacturer&quot;: 2,

}

Right now I'm using DTO and mapping function to map the productDTO to a product:

public class ProductCreationDTO {
    private String name;
    private Long manufacturer;
}

private Product mapProductCreationDTOtoProduct(ProductCreationDTO pcd)
{
    Product p = modelMapper.map(pcd,Product.class); // maps fields with same name that arent nested(like manufacturer)
    Optional&lt;Manufacturer&gt; o = manufacturerService.getManufacturer(pcd.getManufacturer());
    o.ifPresent(m-&gt;p.setManufacturer(m));
    return p;
}

I suceeded doing this converstion in my get calls for objects by adding those 2 annotations above the manufacturer obj in the Product class:

@JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property=&quot;id&quot;)
@JsonIdentityReference(alwaysAsId=true)

Is there a way to using jackson (annotations) to map the post json into a product object (deserialize ) the same it happens during rest get calls(serialize) ?

答案1

得分: 0

以下是翻译好的部分:

所以,我没有使用objectMapper和DTO,而是将我传递的json更改为以下内容:

{
    "name": "巧克力",
    "manufacturer": {"id": 2}
}

感谢@Lkopo的建议 - 在架构方面,最好创建DTO以传输数据。

带有DTO的完整示例 - https://github.com/marielcherkassky/simple_spring_boot_jpa_project

英文:

So instead of using the objectMapper and the DTO I changed the json that I passed to the following :

{
    &quot;name&quot;:&quot;chocolate&quot;,
    &quot;manufacturer&quot;: {&quot;id&quot;:2}

}

Thanks to @Lkopo for the tip - In aspect of architecture it is better to create DTOs in order to transfer data.

Full example with DTO - https://github.com/marielcherkassky/simple_spring_boot_jpa_project

huangapple
  • 本文由 发表于 2020年4月5日 02:19:25
  • 转载请务必保留本文链接:https://java.coder-hub.com/61032733.html
匿名

发表评论

匿名网友

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

确定