正确保留JSON对象

时间:2015-02-16 13:25:38

标签: java json hibernate jpa

我有以下课程:

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对象(主对象)持久化到数据库时,BOTH对象将被持久化。

它出了什么问题?

问题是,类别将以相同的信息再次持久化,但具有不同的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") 两个类之上的注释,但它没有帮助。

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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:-1)

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

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

这种方式类别将是一个附加对象。

相关问题