2013-06-30 13 views
11

私はCircularのリファレンスを持っています。Json and Java - Circular Reference

I私は

java.lang.IllegalStateException: 
    Cannot call sendError() after the response has been committed 

オブジェクトを生成し、結果として、私は無限の応答を得るように、いくつかの参照を持つオブジェクトを返すようにしようとすると、フロントエンドにオブジェクトを返す休憩ウェブサービスは、問題がある持っていますHibernate Code Generationによって自動的に生成され、バックエンドに循環参照が必要です。ジャクソンを使用してフロントエンドに情報を送信する前に、循環参照を削除する必要があります。

コントローラメソッドヘッダは次のとおりです。

@RequestMapping(value="/list", method=RequestMethod.POST) 
public @ResponseBody eventResponse list(@RequestBody String sessionID) { 

私はJSONに変換するexplicite何もしていないよ、私はこれでニュービーだと私はジャクソンがこれを自動的に解決していると思います。

+1

http://wiki.fasterxml.com/JacksonFeatureBiDirReferences –

答えて

23

これには2通りの方法があります。エンティティを外部に公開する必要がある場合は、循環参照の原因となるプロパティに@JsonIgnoreを追加することをお勧めします。これはJacksonにそのプロパティをシリアル化しないように指示します。

もう1つの方法は、Jacksonが提供する双方向機能を使用することです。 @JsonManagedReferenceまたは@JsonBackReferenceのいずれかを使用できます。 @JsonManagedReferenceはプロパティの「前方」部分であり、通常はシリアル化されます。 @JsonBackReferenceは参照の「後ろ」部分です。シリアライズされませんが、 "フォワード"タイプがデシリアライズされると再構築されます。

例​​をご覧ください。

これはあなたのコメントに対処しています。私はあなたがこの場合にしたいと思うかもしれないと思うのは、外界に見えるDTOを使用することです。エンティティを外部に公開したくないため、このアプローチが好きです。これは、ジャクソンの注釈がDTO上であり、エンティティ上ではないことを意味する。エンティティをDTOに変換するある種のマッパーまたはコンバータが必要になります。エンティティを変更すると、マッパー/コンバータを変更しない限り、DTOに伝播しません。あなたがエンティティに変更を加えたときに、その変更を公開するかどうかを決めることができるので、これは大丈夫だと思います。

UPDATE

あなたはジャクソンの双方向の関係を扱うことができるさまざまな方法について詳しく説明します良いブログの記事hereがあります。 @JsonIgnore,@JsonManagedReferenceおよび@JsonBackReference,@JsonIdentityInfo@JsonViewおよびカスタムシリアライザを使用するソリューションについても説明します。これは、あなたが使用できるさまざまなテクニックのかなり包括的な書き方です。

+0

はい、これについて読んでいます。しかし、それは、私がHibernateによって生成されたエンティティに "触れ"たくないということです。データベースが増え続けるので、何かを追加するときはいつでも、すべてのエンティティを再度変更する必要があります。 私が理解しているとおり、両方のオプションのエンティティを変更する必要があります。 – Faabass

+0

なぜdownvote? –

5

単一の注釈@JsonIdentityInfoが問題を解決します。循環参照も扱います。 Reference

+0

唯一の問題は、IDフィールドがnullの場合です。次に正方形1 - 循環参照に戻ります。 – anton1980