将嵌套实体保存在 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
存储帐户和嵌套的帐户标识符吗?
我想避免对不同的端点执行两个 POST
s。使用 @JsonManagedReference
和 @JsonBackReference
有其他不必要的缺点。
当我在 Java 代码中使用实体对象时,它工作得很好。
我觉得你别无选择,必须做各种POST。为了得出这个结论,我为此付出了很多努力,尝试了双向和单向关联。
最简单的方法是在 /account
上使用空 identifiers
POST
,然后在 /accountidentifiers
上使用 account
字段等于location
字段中第一个 POST
的答案,您将不需要再次 PATCH
您的帐户实体来更新关系。
我无法通过 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
存储帐户和嵌套的帐户标识符吗?
我想避免对不同的端点执行两个 POST
s。使用 @JsonManagedReference
和 @JsonBackReference
有其他不必要的缺点。
当我在 Java 代码中使用实体对象时,它工作得很好。
我觉得你别无选择,必须做各种POST。为了得出这个结论,我为此付出了很多努力,尝试了双向和单向关联。
最简单的方法是在 /account
上使用空 identifiers
POST
,然后在 /accountidentifiers
上使用 account
字段等于location
字段中第一个 POST
的答案,您将不需要再次 PATCH
您的帐户实体来更新关系。