将嵌套实体保存在 Spring 数据中

Saving nested entities in Spring Data Rest

我无法通过 REST 使用 Spring Data Rest 保存我的实体。 正如你在下面看到的,我有一个循环依赖,我试图用 Jackson 来解决。这是一个解释问题的小例子。

账户

@Entity
@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator.class)
public class Account implements Serializable
{
    @Id <...>
    private Long id;

    private String uid;

    @OneToMany <...>
    //@JsonIdentityReference
    private List<AccountIdentifier> identifiers;

    // Getters, Setters ...
}

帐户标识符

@Entity
@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator.class)
public class AccountIdentifier implements Serializable
{
    @Id <...>
    private Long id;

    private String value;

    @ManyToOne <...>
    //@JsonIdentityReference(alwaysAsId = true)
    private Account account;

    // Getters, Setters ...
}

账户资料库

@RepositoryRestResource(collectionResourceRel = "accounts", path = "accounts")
public interface AccountRepository extends PagingAndSortingRepository<Account, Long>

AccountIdentifierRepository

@RepositoryRestResource(collectionResourceRel = "accountidentifiers", path = "accountidentifiers")
public interface AccountRepository extends PagingAndSortingRepository<AccountIdentifier, Long>

通过此设置,我可以完美地读取存储在我的数据库中的值。

当我想通过 POST 将值保存到我的 /accounts 端点时,问题就开始了。我想保存以下 JSON:

 '{"id":null, "uid":"test-uid", "identifiers":[{"id":null,"value":"test-value"}]}'

这引发了一个 JsonMappingException:

com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: demo.domains.AccountIdentifier["account"]->demo.domains.Account["identifiers"]->java.util.ArrayList[0]->demo.domains.AccountIdentifier["account"]-[...]

当我用 @JsonIdentityReference 注释两个实体时,我在循环引用中得到 NullPointerExceptions

com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: demo.domains.Account["identifiers"]->java.util.ArrayList[0]->demo.domains.AccountIdentifier["account"])

有什么方法可以用 "id":null 存储帐户和嵌套的帐户标识符吗? 我想避免对不同的端点执行两个 POSTs。使用 @JsonManagedReference@JsonBackReference 有其他不必要的缺点。

当我在 Java 代码中使用实体对象时,它工作得很好。

我觉得你别无选择,必须做各种POST。为了得出这个结论,我为此付出了很多努力,尝试了双向和单向关联。

最简单的方法是在 /account 上使用空 identifiers POST,然后在 /accountidentifiers 上使用 account 字段等于location 字段中第一个 POST 的答案,您将不需要再次 PATCH 您的帐户实体来更新关系。