我已经在网上和SO上进行了搜索,并且找到了针对此问题的几种解决方案,但是由于我的项目的配置,它们都不起作用或不适用.特别是,这是我尝试过的: 解决方案1:使用@JsonManagedReference/@JsonBackReference 这似乎是最建议的解决方案.但是,这仅适用于(据我所知)一对多或多对一关系,因为@JsonBackReference批注不支持集合(列表,数组,集合等).或者至少,这就是文档所说的,并且在尝试时我得到了一个似乎可以证实这一点的异常.我在网上找到了几个在List上使用此批注的示例,但对我来说却行不通.如果有人对此有任何线索,请详细说明. 解决方案2:不要使用@JsonIgnore 来保持关系的一侧将@JsonIgnore添加到一个字段中,如下所示:@ManyToMany()@JoinTable(name = "email_pratica", joinColumns = { @JoinColumn(name = "fk_email_id")}, inverseJoinColumns = { @JoinColumn(name = "fk_pratica_id")})@JsonIgnoreprivate List<Pratica> pratiche;打破无限循环,因此可以工作.这也适合我,因为我真的不需要Email对象上的Pratica列表,所以我从不使用它.但是,这带来了另一个大问题:每当我将对象持久化到数据库中时,Pratica的列表将为空(因为在JSON序列化期间丢失了),因此Hibernate将从我的Join Table中删除关联记录. /p> 解决方案3:使用@JsonIdentityInfo 此解决方案需要Jackson 2.x,但是不幸的是,由于服务器无法控制的限制,我只能使用RESTeasy(resteasy-jackson-provider 2.3.6)提供的Jackson版本,其中提供了Jackson 1.x 解决方案4:使用自定义的序列化器/解串器 请参阅解决方案3.即使@JsonSerialize/@JsonDeserialize批注包含在Jackson 1.1中,似乎它们也未包含在RESTeasy提供的版本中,或者至少编译器找不到引用,所以我假设是这种情况.那么,毕竟……对于我所拥有的限制,有没有解决此问题的解决方案?可以以非骇客的方式完成吗?如果不能,那么少乱"的非hacky方式是什么?解决方案您正在将数据库对象与json混合在一起,我认为这是主要问题,主要是设计缺陷. 当您要使用json以外的数据序列化数据时,必须更改持久性层.如果要更改持久性层,则也必须更改json内容. 更糟糕的是:假设您要对表示层进行单元测试-假设您在前端中使用json-在没有持久性层的情况下如何做到这一点?所以我的答案是:分开您的担忧,将json与持久性脱钩.I'm using Hybernate to persist some beans that have a Many-To-Many relationship. Here are the two beans: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; }}This works correctly, however the problem is that I then need to serialize/deserialize these beans using JSON. Doing this causes an infinite recursion, since each object Email tries to serialize all of its objects Pratica, which in turn try to serialize all their Emails and so on, until a StackOverflow exception occours.I've searched online and here on SO, and I've found several solutions to this problem, however none of them work or are applicable, due to the configuration of my project. In particular, here's what I've tried:Solution 1: using @JsonManagedReference / @JsonBackReferenceThis seems to be the most suggested solution. However, this only works (as far as I can tell) for One-To-Many or Many-To-One relationships, since the @JsonBackReference annotation does not support collections (Lists, Arrays, Sets, etc.). Or at least, this is what the documentation says and when trying I got an exception that seems to confirm this. I've found a couple of examples online that use this annotation on a List, but for me it didn't work. If anyone has any clue on this, please elaborate.Solution 2: do not persist one side of the relationship using @JsonIgnoreAdding @JsonIgnore to one of the fields, like this:@ManyToMany()@JoinTable(name = "email_pratica", joinColumns = { @JoinColumn(name = "fk_email_id")}, inverseJoinColumns = { @JoinColumn(name = "fk_pratica_id")})@JsonIgnoreprivate List<Pratica> pratiche;breaks the infinite loop, and thus works. It would also suit me, since I don't really need the list of Pratica on the Email objects, I never use it.However, this introduces another big problem: whenever I persist the object back to the database the list of Pratica will be empty (since it was lost during JSON serialization), and thus Hibernate will delete the association record from my Join Table.Solution 3: using @JsonIdentityInfoThis solution needs Jackson 2.x, but unfortunately, due to restrictions on the server that are beyond my control, I can only use the version of Jackson provided by RESTeasy (resteasy-jackson-provider 2.3.6), which provides a subset of Jackson 1.xSolution 4: using a custom serializer/deserializerSee solution 3. Even tho the @JsonSerialize/@JsonDeserialize annotations are included in Jackson 1.1, it seems they're not included in the version provided by RESTeasy, or at least the compiler can't find the references, so I assume this is the case.So, after all this... is there a clean solution to this problem with the restrictions I have? Can it be done in a non-hacky way? And if it can't, what is the "less messy" non-hacky way? 解决方案 You're mixing database objects with json, that's in my opinion the main problem, the main design flaw. When you want to serialize your data with something other than json, you have to change your persistency layer. If you want to change your persistency layer, you have to change your json stuff, too. And worse: Let's say you want to unit test your presentation layer - assuming you use json in your frontend - how are you going to do that, without your persistency layer?So my answer is: Separate your concerns, decouple json from persistency. 这篇关于休眠多对多和JSON序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-28 05:50