具有刷新嵌套实体策略的JPA持久化实体

时间:2017-10-02 19:41:39

标签: java hibernate jpa

我在质疑自己如何执行以下方案:

我们来看一个示例实体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应该有很多CategoryItem无法直接创建或更新Category,它必须使用现有的Category(成像管理员管理的类别下拉列表。这就是Cascade.PERSISTCascade.MERGE丢失的原因。

现在想象一下具有此类JSON请求结构的API POST /api/items

{
    "name": "new item",
    "categories": [
        "6d126e36-a7a5-11e7-abc4-cec278b6b50a",
        "88d5a052-a7a5-11e7-abc4-cec278b6b50a"
    ]
}

这应该使用现有的Category创建新项目,并使用给定的 ID (考虑到这些ID是正确且存在的)。

但是我会返回包含complet嵌套实体值的响应:

{
    "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)。< / p>

那么检索Category字段的最佳方法是什么?

  1. 我应该在refresh(item)之后使用persist(item)吗?
  2. 我应该使用附加 Category代替分离,从而在Category之前使用id获取每个persist(item)
  3. 我可以对请求POST请求正文)和响应使用相同的表示形式,因此名称将被预先填写。但如果id正确但name不正确(因为我不接受来自Category的{​​{1}}更新),会发生什么?只需忽略Item或引发异常?
  4. 其他方式
  5. 另外如果2.是最佳解决方案,我应该在哪里获取那些嵌套实体?我的意思是name表示层),Controller表示层),DtoToEntityMapper服务层)

    PS:请严格遵守Service规范,不要使用JPA具体功能。 PS2:我可以在单Hibernate个请求

    中完成

1 个答案:

答案 0 :(得分:1)

使用dat <- read.table(text = " track_id tag1 tag2 1 1550729 54087 109806 2 1184201 201327 3668 ", header = TRUE) dat molten <- reshape2::melt(dat, id.vars = "track_id") xtabs(~ track_id + value, molten) # value #track_id 3668 54087 109806 201327 # 1184201 1 0 0 1 # 1550729 0 1 1 0 代替entityManager.merge()应该可以解决问题。它将返回托管实例,因此访问其类别应该为您提供包括描述在内的类别。

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