【问题标题】:Persisting JSON object properly正确持久化 JSON 对象
【发布时间】:2023-03-27 09:55:02
【问题描述】:

我有以下课程:

public class Entity {

@Id 
@GeneratedValue(strategy = GenerationType.AUTO)
private Long Id;
private String name;

@JsonManagedReference
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Category category;

//Constructors, getters and setters
}


public class Category {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long Id;
private String name;

@JsonBackReference
@OneToMany(mappedBy = "category", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Entity> entity;

//Constructors, getters and setters
}

我有一个表单,当我提交表单时,我得到以下 JSON:

{
 id: "1"
 name: "EntityA"
 category: {    
    id: "4"
    name: "categoryA"
 }
}

CategoryA 已在数据库中。当我将 EntityA 对象(主对象)持久化到数据库时,两个对象都将被持久化。

有什么问题?

问题是该类别将使用相同的信息但具有不同的 id 再次持久化。因此,当我将上述对象 EntityA 持久保存在数据库中时,它会很好地保存,但即使它存在于数据库中,也会以不同的 id 再次保存类别。

以下是从数据库的角度来看的步骤。

初始数据库:

实体表(空)

|id | name | category_id |
--------------------------
|   |      |             |

分类表

| id | name    |
----------------
|  4 |categoryA|

Entity_category 表(空)

| entity_id | category_id |
---------------------------
|           |             | 

坚持后

实体表(空)

id | name  | category_id |
--------------------------
 1 |EntityA| 5           |

Entity_category 表(不应为空,而是为空)

| entity_id | category_id |
---------------------------
|           |             | 

分类表

id | name    |
--------------
 4 |categoryA|
 5 |categoryA|

我想要的只是当我持久化 EntityA 的对象时,它不会持久化类别,而是更新它与 EntityA 的关系。持久化后第二个视图的 category_id 应该是 4 而不是 5。

我使用实体管理器的 persist() 方法来持久化对象。

我使用的技术是 jackson 2.0、Hibernate、Postgres 作为数据库。

我也测试过@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") 两个类上方的注释,但没有帮助。

我在这里做错了什么?任何帮助表示赞赏。

【问题讨论】:

    标签: java json hibernate jpa


    【解决方案1】:

    您尚未将 Id 标记为实体的主键 (@Id)。在您的情况下,似乎 id 是一个自动增量列(这就是为什么 id 与您插入的不同)并且 JPA 无法检测到该对象是同一个。尝试用注解@Id @GeneratedValue 标记ID 字段,然后重试。

    【讨论】:

    • 我还注意到您与这些实体有 ManyToOne-OneToMany 关系。我认为 U 不需要具有这种关系的额外连接表(Entity_category)。 JPA 也不会使用它
    • 对不起,我忘了补充。它已经在我的代码中。我现在在这里添加它。感谢您指出。
    • 那些注释无济于事。同样的问题仍然存在。
    • 为什么不使用合并而不是持久化?在这种情况下,它将充当 SaveOrUpdate
    • 出现同样的问题,合并也无济于事。
    【解决方案2】:

    好的,我终于找到了解决方案。整个问题是因为我在json类别对象键“id”中写了一个小“I”字母,这意味着它找不到类别id,因为它与实体类的Id字段不匹配从而产生具有null id 的类别。这就是为什么它将类别作为新实体持久化的原因,因为它在反序列化过程后无法在数据库中找到这样的对象。

    确保当您持久化您的 json 对象时,json 中的每个键必须与您的实体类字段或属性完全匹配。

    【讨论】:

      【解决方案3】:

      尝试获取对类别的引用并在提交/合并之前手动设置引用(如果在数据库中找到):

      Category category = em.find(Category.class, entity.getCategory().getId());
      if (category!=null){
        entity.setCategory(category);
      }
      

      这样类别将是一个附加对象。

      【讨论】:

      • 这没有任何帮助。
      • 是的,但请记住,您以 json 形式获取对象,这意味着您在上面添加的代码需要对 json 对象进行反序列化,以便在 java 中正确使用它。这再次意味着需要更多的反序列化逻辑。例如,您使用其 id 搜索适当的类别。类别 id 在 json 对象中。
      • 我同意你的观点,这是我发布解决方案时的想法。具体的解决方法必须分两步完成。反序列化然后附加类别对象。这不是一步到位的解决方案。
      • 查看此链接以获取提示:stackoverflow.com/questions/17874688/….
      猜你喜欢
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多