繁体   English   中英

JPA通过刷新嵌套实体策略来持久化实体

[英]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.PERSISTCascade.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"
        }
    ]
}

为了避免样板,假设DtoDtoToEntityMapper (和反向)存在并且如预期工作。

问题是当我将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字段的最佳方法是什么?

  1. 我应该在persist(item)之后使用refresh(item) persist(item)吗?
  2. 我应该使用附加 Category而不是分离 Category ,从而在persist(item)之前使用id获取每个Category吗?
  3. 我可以使用相同的表示形式来表示请求POST请求正文)和response ,因此名称将被预先填写。 但是,如果id正确但name不正确怎么办(因为我不接受Item Category更新)? 只是忽略name或引发异常?
  4. 另一种方式

另外,如果2.是最佳解决方案,那我应该在哪里获取这些嵌套的实体? 我的意思是在Controller表示层 ), DtoToEntityMapper表示层 ), Service服务层 )中


PS:请我坚持使用JPA规范,而不使用Hibernate特定功能。 PS2:我可以在单个POST请求中执行

使用entityManager.merge()而不是entityManager.persist()应该可以解决问题。 它将返回托管实例,因此访问其类别应为您提供包括描述的类别。

注意:请确保在调用后使用托管实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM