[英]JPA persist entity with refreshing nested entity strategy
我在问自己如何执行以下方案:
我们来看一个示例实体Item
@Data
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@Entity
class Item implements Serializable {
@Id
@GeneratedValue
@Setter(AccessLevel.NONE)
private UUID id;
private String name;
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.REFRESH})
@JoinTable(name = "item_category", joinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "category_id", referencedColumnName = "id")})
private Set<Category> categories;
@PrePersist
protected void generateUuid() {
id = UUID_GENERATOR.generate();
}
}
和Category
@Data
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@Entity
class Category implements Serializable {
@Id
@GeneratedValue
@Setter(AccessLevel.NONE)
private UUID id;
private String name;
@PrePersist
protected void generateUuid() {
id = UUID_GENERATOR.generate();
}
}
在我的用例中, Item
应该具有多个Category
但是Item
无法直接创建或更新Category
,它必须使用现有的Category
(图像是由管理员管理的类别的下拉列表)。 这就是为什么缺少Cascade.PERSIST
和Cascade.MERGE
原因。
现在想象一下具有此类JSON请求结构的API POST /api/items
{
"name": "new item",
"categories": [
"6d126e36-a7a5-11e7-abc4-cec278b6b50a",
"88d5a052-a7a5-11e7-abc4-cec278b6b50a"
]
}
那应该创建一个具有给定ID的现有Category
的新项目 (考虑到ID是正确的并且存在)。
但是,我将返回包含完整嵌套实体值的响应:
{
"name": "new item",
"categories": [
{
"id": "6d126e36-a7a5-11e7-abc4-cec278b6b50a",
"name": "CAT_A"
},
{
"id": "88d5a052-a7a5-11e7-abc4-cec278b6b50a",
"name": "CAT_B"
}
]
}
为了避免样板,假设Dto
和DtoToEntityMapper
(和反向)存在并且如预期工作。
问题是当我将persist()
新的Item
实体从JSON生成时:
Item(
id=null,
name="new item",
Categories:[
Category(
id="6d126e36-a7a5-11e7-abc4-cec278b6b50a",
name=null
),
Category(
id="6d126e36-a7a5-11e7-abc4-cec278b6b50a",
name=null
)
]
)
下面的每个实例都是分离的 。
问题是在persist()
每个Category
实例似乎都已分离(或至少name
仍等于null
)。
那么检索Category
字段的最佳方法是什么?
persist(item)
之后使用refresh(item)
persist(item)
吗? Category
而不是分离 Category
,从而在persist(item)
之前使用id
获取每个Category
吗? POST
请求正文)和response ,因此名称将被预先填写。 但是,如果id
正确但name
不正确怎么办(因为我不接受Item
Category
更新)? 只是忽略name
或引发异常? 另外,如果2.是最佳解决方案,那我应该在哪里获取这些嵌套的实体? 我的意思是在Controller
( 表示层 ), DtoToEntityMapper
( 表示层 ), Service
( 服务层 )中
PS:请我坚持使用JPA
规范,而不使用Hibernate
特定功能。 PS2:我可以在单个POST
请求中执行
使用entityManager.merge()
而不是entityManager.persist()
应该可以解决问题。 它将返回托管实例,因此访问其类别应为您提供包括描述的类别。
注意:请确保在调用后使用托管实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.