gpt4 book ai didi

java - Hibernate 多对多和 JSON 序列化

转载 作者:行者123 更新时间:2023-11-29 09:28:05 28 4
gpt4 key购买 nike

我正在使用 Hybernate 来保存一些具有多对多关系的 bean。这是两个 bean :

Email.java

@Entity
@NamedQuery(name = "Email.findAll", query = "SELECT e FROM Email e")
public class Email implements Serializable {
private static final long serialVersionUID = 1L;

//... other fields ...

// bi-directional many-to-many association to Pratica
@ManyToMany()
@JoinTable(name = "email_pratica", joinColumns = {
@JoinColumn(name = "fk_email_id")
}, inverseJoinColumns = {
@JoinColumn(name = "fk_pratica_id")
})
private List<Pratica> pratiche;

public List<Pratica> getPratiche() {
return this.pratiche;
}

public void setPratiche(List<Pratica> pratiche) {
this.pratiche = pratiche;
}

}

Pratica.java

@Entity
@NamedQuery(name = "Pratica.findAll", query = "SELECT p FROM Pratica p")
public class Pratica extends AtstTable implements Serializable {
private static final long serialVersionUID = 1L;

//... other fields ...

// bi-directional many-to-many association to Email
@ManyToMany(mappedBy = "pratiche", fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.PERSIST})
private List<Email> emails;

public List<Email> getEmails() {
return this.emails;
}

public void setEmails(List<Email> emails) {
this.emails = emails;
}

}

这工作正常,但问题是我需要使用 JSON 序列化/反序列化这些 bean。这样做会导致无限递归,因为每个对象 Email 都会尝试序列化其所有对象 Pratica,而后者又会尝试序列化所有的 Email s 等等,直到发生 StackOverflow 异常。

我在网上和此处搜索过 SO,我找到了解决这个问题的几种方法,但是由于我的项目配置,它们都不起作用或不适用。特别是,这是我尝试过的:

解决方案 1:使用 @JsonManagedReference/@JsonBackReference

这似乎是最受推荐的解决方案。但是,这仅适用于一对多或多对一关系(据我所知),因为 @JsonBackReference 注释不支持集合(列表、数组、集合、 ETC。)。或者至少,这就是文档所说的,并且在尝试时我得到了一个似乎证实了这一点的异常。我在网上找到了几个在列表上使用此注释的示例,但对我来说它不起作用。如果有人对此有任何线索,请详细说明。

解决方案 2:不要使用 @JsonIgnore

保留关系的一侧

@JsonIgnore 添加到其中一个字段,如下所示:

@ManyToMany()
@JoinTable(name = "email_pratica", joinColumns = {
@JoinColumn(name = "fk_email_id")
}, inverseJoinColumns = {
@JoinColumn(name = "fk_pratica_id")
})
@JsonIgnore
private List<Pratica> pratiche;

打破无限循环,因此有效。它也适合我,因为我真的不需要 Email 对象上的 Pratica 列表,所以我从不使用它。然而,这引入了另一个大问题:每当我将对象持久化回数据库时,Pratica 列表将是空的(因为它在 JSON 序列化期间丢失),因此 Hibernate 将从中删除关联记录我的连接表。

解决方案 3:使用 @JsonIdentityInfo
此解决方案需要Jackson 2.x,但不幸的是,由于我无法控制的服务器限制,我只能使用RESTeasy提供的Jackson版本(resteasy-jackson-provider 2.3.6),它提供了 Jackson 1.x

的一个子集

解决方案 4:使用自定义序列化器/反序列化器
请参阅解决方案 3。即使 @JsonSerialize/@JsonDeserialize 注释包含在 Jackson 1.1 中,但似乎它们未包含在版本中由 RESTeasy 提供,或者至少编译器找不到引用,所以我假设是这种情况。

那么,在这一切之后...是否有针对我的限制的干净解决方案?可以以非 hacky 方式完成吗?如果不能,什么是“不那么困惑”的非 hacky 方式?

最佳答案

您将数据库对象与 json 混合在一起,我认为这是主要问题,主要设计缺陷。

当你想用 json 以外的东西序列化你的数据时,你必须改变你的持久层。如果你想改变你的持久层,你也必须改变你的 json 东西。

更糟糕的是:假设您想对表示层进行单元测试 - 假设您在前端使用 json - 如果没有持久层,您将如何进行测试?

所以我的答案是:分离你的关注点,将 json 与持久性分离。

关于java - Hibernate 多对多和 JSON 序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41260579/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com