【问题标题】:Spring CrudRepository save excluding child entity in JSON?Spring CrudRepository 保存不包括 JSON 中的子实体?
【发布时间】:2018-05-27 08:52:46
【问题描述】:

我有一个 SpringBoot 应用程序,并且正在使用 CrudRepository 将对象持久保存到数据库。我有一个产品实体类,它与供应商实体具有多对一的关系。我传递的 JSON 包含产品和嵌入式供应商的详细信息,但我最终只想传递产品详细信息并包含 vendorID。是否有一些注释可以为我解决这个问题?

这是我的代码:

@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @ManyToOne
    @JoinColumn(name="VendorID")
    private Vendor vendor;
    @Column(name="partnumber")
    @JsonProperty("PartNumber")
    private String vendorPartNumber;
    @JsonProperty("Name")
    private String name;

@Entity
public class Vendor {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@JsonProperty("Code")
private String code;
@JsonProperty("Name")
private String name;
....
@OneToMany(mappedBy = "vendor", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonIgnore
private List<Product> products;

我传递的 JSON(有效)如下所示:

    {
    "Vendor": {
        "Id":1,
        "Code": "BB-1001",
        "Name": "Best Buy",
        "Address": "100 Best Buy Street",
        "City": "Louisville",
        "State": "KY",
        "Zip": "40207",
        "Phone": "502-111-9099",
        "Email": "geeksquad@bestbuy.com",
        "IsPreApproved": "false"
    },
    "PartNumber":"TEST01",
    "Name":"Test Product 01",
    "Price":99.99
}

我最终想删除对供应商的 JSON 对象引用并替换为 VendorId。

【问题讨论】:

  • 定义一个 DTO 而不是与 Entity 战斗,只添加必要的字段。
  • 感谢您的快速回复!我现在正在调查和测试。

标签: json spring spring-data-jpa


【解决方案1】:

通过注解解决

您可以使用@JsonSerialize 提供自定义序列化来实现您想要的。

@Entity
public class Product {

    ...

    @JsonSerialize(using = VendorToIdSerializer.class)
    @ManyToOne
    @JoinColumn(name="VendorID")
    private Vendor vendor;

    ...
}

public class VendorToIdSerializer extends JsonSerializer<Vendor> {

    @Override
    public void serialize(Vendor vendor, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        String vendorIdAsString = String.valueOf(vendor.getId());
        jsonGenerator.writeObject(vendorIdAsString);
    }
}

DTO 解决方案

但是,正如其他人所指出的,更简洁的方法是创建一个 DTO 类,该类充当Product 的“视图”角色。

public class ProductView {

    private final int vendor;
    ...

    public ProductView(Vendor vendor) {
        this.vendor = vendor.getId();
        ...
    }

    // getters
}

【讨论】:

    【解决方案2】:

    使用@JsonBackReference 和@JsonManagedReference 注释回答了我的问题。不过,我将继续按照上面的建议研究 DTO。谢谢!

    【讨论】:

      【解决方案3】:

      我还建议创建一个适合您需求的 DTO。

      使用 JPA,您可以使用构造函数表达式创建 DTO 实例:

      这里是 Vlad Mihalcea 撰写的一篇精彩文章中的一个示例 https://vladmihalcea.com/the-best-way-to-map-a-projection-query-to-a-dto-with-jpa-and-hibernate/

      List<PostDTO> postDTOs = entityManager.createQuery(
          "select new " +
          "   com.vladmihalcea.book.hpjp.hibernate.query.dto.projection.jpa.PostDTO(" +
          "       p.id, " +
          "       p.title " +
          "   ) " +
          "from Post p " +
          "where p.createdOn > :fromTimestamp", PostDTO.class)
          .setParameter( "fromTimestamp", Timestamp.from(LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )
              .toInstant( ZoneOffset.UTC ) ))
          .getResultList();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-23
        • 1970-01-01
        • 1970-01-01
        • 2018-08-21
        相关资源
        最近更新 更多