多対多の関係を持ついくつかのBeanを永続化するためにHybernate
を使用しています。ここでは、2つの豆は、次のとおりです。Hibernate多対多およびJSON直列化
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
を使用しています。各オブジェクトEmail
は、すべてのオブジェクトPratica
をシリアル化しようとします。Email
などをシリアル化しようとします(StackOverflow
例外が発生するまで)。
私はこれをオンラインで検索しましたが、この問題の解決策はいくつか見つかりましたが、私のプロジェクトの構成上、この問題は解決されていません。特に、ここで私が試したものです:
ソリューション1:これは、ほとんどの提案された解決策であるように思わ@JsonManagedReference
/@JsonBackReference
使用。しかし、@JsonBackReference
アノテーションはコレクション(リスト、配列、セットなど)をサポートしていないため、これは(一対一の関係または多対1の関係について)(私が言う限りでは)動作します。あるいは、少なくとも、これはドキュメンテーションが言っていることであり、試してみると、これを確認するような例外があります。私はリスト上でこのアノテーションを使用するオンラインの例をいくつか見つけましたが、私にとってはうまくいきませんでした。誰かがこれについて何か手がかりがある場合は、詳しく説明してください。
解決方法2:
@ManyToMany()
@JoinTable(name = "email_pratica", joinColumns = {
@JoinColumn(name = "fk_email_id")
}, inverseJoinColumns = {
@JoinColumn(name = "fk_pratica_id")
})
@JsonIgnore
private List<Pratica> pratiche;
は無限ループを壊すので、動作します。このように、フィールドのいずれかに@JsonIgnore
を追加@JsonIgnore
を使用して関係の一の側面を保持されません。それはEmail
オブジェクトにPratica
のリストが本当に必要なわけではないので、私にも合っています。決して使っていません。 しかし、これは別の大きな問題を引き起こします。オブジェクトをデータベースに保存するたびに、Praticaのリストは空になります(JSON
シリアライゼーション中に失われてしまいます)。そのため、Hibernateは結合テーブルから関連レコードを削除します。
解決策3:提供@JsonIdentityInfo
RESTeasy
(resteasy-jackson-provider 2.3.6
)が提供するジャクソンのバージョンをこのソリューションはJackson 2.x
必要がありますが、残念ながら、私のコントロールを超えているサーバー上の制約のために、私は使用することができます使用して@JsonSerialize
/@JsonDeserialize
注釈が私であってもカントーカスタム・シリアライザ/デシリアライザを使用すると
を参照してくださいソリューション3:Jackson 1.x
溶液4のサブセットJackson 1.1
にncluded、それはRESTeasyが提供するバージョンに含まれていないか、少なくともコンパイラが参照を見つけることができないと思われるので、私はこれが当てはまると仮定します。
だからこそ、この問題には、私が持っている制限がありますか?それは非ハッキーな方法で行うことができますか?それができないのであれば、「ハッピーでない」ハッキーではない方法は何ですか?
一方の側で '@JsonIgnore'を使用している場合と、永続化/更新を手動で(再)接続する必要がある場合は、唯一の方法です。特にコレクション上で '@ JsonBackReference'をサポートしているかもしれない新しいバージョンに更新することはできません(私はそれをチェックしていませんが、それは良い考えです)。この問題は、JSONが自然に内部参照をサポートする形式ではないという事実から発生します。 – coladict
@coladict:そうです、それは私が現在やっていることです。他のクリーンな方法があるかどうかを確認するために質問を投稿しました。 –