有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java正确持久化JSON对象

我有以下课程:

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"
 }
}

分类已经在数据库中。当我将一个对象(主对象)持久化到数据库时,这两个对象都将被持久化

有什么问题吗

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

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

初始数据库:

实体表(空)

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

类别表

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

实体_类别表(空)

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

坚持之后

实体表(空)

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

实体_类别表(不应为空,但为空)

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

类别表

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

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

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

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

我还测试了@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") 注释在这两个类之上,但它没有帮助

我做错了什么?感谢您的帮助


共 (3) 个答案

  1. # 1 楼答案

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

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

    这样,类别将成为附着的对象

  2. # 2 楼答案

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

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

  3. # 3 楼答案

    您尚未将Id标记为实体中的主键(@Id)。在您的例子中,id似乎是一个自动递增列(这就是id与您插入的内容不同的原因),而JPA无法检测到对象是否是同一个。尝试用注释@Id @GeneratedValue标记ID字段,然后重试