Spring 数据其余:与非导出实体相关的 POSTing 实体

Spring Data Rest: POSTing entity with relation to non-exported entity

我有一个通过 Spring Data Rest 导出的实体类型,并且与没有自己的 REST 端点的实体有关系:

@Data
@NoArgsConstructor
@EqualsAndHashCode
@Entity
public class Request {

    ...

    @NotNull
    @OneToOne(cascade = CascadeType.ALL)
    @Immutable
    private Address address;

"Address" 类型大致如下所示加上地址的常用内容 ;)

@NoArgsConstructor
@Entity
@Getter
@Setter
public class Address {

    @Id
    @GeneratedValue
    private Long id;

有一个 RequestRepo 扩展了 CrudRepository 但没有地址类型的存储库。

这就是我所做的: 1. GET一个特定的Request实体 2. 修改一个属性的Request(不是地址) 3. PUT整个请求

我注意到,在处理程序的 @BeforeSave 注释方法中,地址 属性 的 ID 为 "null"。所以它似乎没有在数据库中查找该地址,而是简单地创建了一个新地址。

嗯,我知道由于没有发布 id,因此无法知道这应该是数据库中的哪个地址。有道理。

在处理程序中,我想检查地址是否已更改,然后根据该信息执行操作。因此,我从数据库中获取旧版本的请求并比较两个地址的 ID,这当然会导致 NullPointerException,因为发布的地址的 ID 为空。我的快速解决方案是实现 equals() 省略 ID 并使用该方法进行比较。

但我想知道还有哪些其他方法。有什么想法吗?

我会让一个地址成为一个可嵌入的而不是一个实体:一个地址不能没有请求而存在,并且它本身不是一个实体。您不太可能想要查询地址。如果您有许多实体共享同一地址,这可能会有所不同,但它是一对一的,所以您不需要。

您可以使用@SecondaryTable保持相同的数据库结构。

要求:

@Data
@NoArgsConstructor
@EqualsAndHashCode
@Entity
@Table(name = "requests")
@SecondaryTable("name = "addresses")
public class Request {

    @NotNull
    @Embedded
    private Address address;
}

地址:

@NoArgsConstructor
@Embeddable
@Getter
@Setter
public class Address {

    @Column(name="town", table="addresses")
    private String town;
}

现在在 PUT 上将更新现有地址。