无法发布集合 [英] Can't POST a collection

查看:13
本文介绍了无法发布集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的实体,其中映射了一个集合.

I have a simple Entity with a single collection mapped.

@Entity
public class Appointment Identifiable<Integer>   {  

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @JsonIgnore
    private Integer id;

    @Column(name="TRAK_NBR")
    private String trackNumber;

    @OneToMany(fetch =FetchType.EAGER, cascade= CascadeType.ALL)
    @JoinColumn(name="CNSM_APT_VER_WRK_I", nullable = false)
    private Set<Product> products = new HashSet<Product>();
}

@Entity
public class Product implements Identifiable<Integer> {

    @Id
    @Column(name = "CNSM_PRD_VER_WRK_I")
    @GeneratedValue(strategy = GenerationType.AUTO)
    @JsonIgnore
    private Integer id;

    @Column(name = "PRD_MDL_NBR")
    private String model;

    @Column(name = "PRD_SPEC_DSC")
    private String description;
}

在我的应用程序中,当我只包含一个用于约会的 PagingAndSortingRepository 时.我可以使用以下有效负载调用 POST 命令.

In my application when I only include a PagingAndSortingRepository for Appointment. I can call the POST command with the following payload.

{
  "trackNumber" : "XYZ123",
  "products": [
    {"model" : "MODEL",
     "description" : "NAME"
    }]
}

当我为 Product 添加 PagingAndSortingRepository 并尝试相同的 POST 时,我收到以下错误消息.

When I add a PagingAndSortingRepository for Product and try the same POST I get the following error message.

{
  "cause" : {
    "cause" : {
      "cause" : null,
      "message" : null
    },
    "message" : "(was java.lang.NullPointerException) (through reference chain: com..model.Appointment[\"products\"])"
  },
  "message" : "Could not read JSON: (was java.lang.NullPointerException) (through reference chain: com.model.Appointment[\"products\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.model.AppointmentVerification[\"products\"])"
}

My GET payload with both Repositories returns this.  This is my desired format.  The link to products should be included

{
  "trackNumber" : "XYZ123", 
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/consumerappointment/appointments/70"
    },
    "products" : {
      "href" : "http://localhost:8080/consumerappointment/appointments/70/products"
  }
}

只有约会存储库,我才能获得以下有效负载,并且可以发布产品列表.

With only the Appointment repository I get the following payload and can post the list of products.

{
  "trackNumber" : "XYZ123",
  "products" : [ {
    "model" : "MODEL",
    "description" : "NAME",
  } ],
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/consumerappointment/appointments/1"
    }
  }
}

推荐答案

让我们退后一步,确保您了解这里发生的事情:如果检测到存储库,Spring Data REST 会公开一个 专用资源集,用于管理由通过 HTTP 存储库.因此,如果您有多个相互关联的实体的存储库,则该关系表示为链接.这就是为什么在您创建 ProductRepository 后,您会看到仅内联有 AppointmentRepositoryproducts 链接的产品.

Let's take a step back and make sure you understand what's happening here: if a repository is detected, Spring Data REST exposes a dedicated set of resources for it to manage the aggregates handled by the repository via HTTP. Thus, if you have repositories for multiple entities related to each other, the relationship is represented as a link. This is why you see the products inlined with only the AppointmentRepository in place and the products link in place once you create a ProductRepository.

如果要将两个存储库公开为资源,则需要在 POST 的有效负载中传递 Product 实例的 URI 以创建 Appointment.这意味着,而不是发布这个:

If you want to expose both repositories as resources, you need to hand the URIs of the Product instances in the payload for the POST to create an Appointment. That means, instead of posting this:

{ "trackNumber" : "XYZ123",
  "products": [
    { "model" : "MODEL",
      "description" : "NAME"
    }
  ]
}

您首先要创建一个Product:

POST /products
{ "model" : "MODEL",
  "description" : "NAME" }

201 Created
Location: …/products/4711

然后将产品的 ID 交给 Appointment 负载:

And then hand the ID of the product to the Appointment payload:

{ "trackNumber" : "XYZ123",
  "products": [ "…/products/4711" ]}

如果您不想要任何这些(首先没有为 Product 公开资源,请在 上使用 @RepositoryRestResource(exported = false)PersonRepository.那仍然会给你留下为 repo 创建的 bean 实例,但没有导出资源,并且为 Appointment 公开的资源回到内联相关的 Products.

In case you don't want any of this (no resources exposed for Product in the first place, use @RepositoryRestResource(exported = false) on PersonRepository. That would still leave you with the bean instance created for the repo, but no resources exported and the resource exposed for Appointments back to inlining related Products.

这篇关于无法发布集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆