14

私はエンティティを持っています:

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column
    private String title;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
    private List<Genre> genre;

}

次に、本を取得することを目的としたコントローラーがあります。私の問題は、コントローラーのjson応答にジャンルフィールドが含まれていることです。ジャクソンがオブジェクトをシリアル化するときに遅延ロードされるフィールドを除外する方法はありますか?

これは私の ObjectMapper の構成です:

Hibernate4Module hm = new Hibernate4Module();
hm.configure(Hibernate4Module.Feature.FORCE_LAZY_LOADING, false);
registerModule(hm);
configure(SerializationFeature.INDENT_OUTPUT, true);

ありがとう!

シリアライゼーションボックスから永久に取り出されるため、JsonIgnore としてマークすることはできません。本と一緒にジャンルを取得する必要がある場合もありますが、それまでにクエリで "fetch join" を使用して null にならないようにします。

4

5 に答える 5

12

これは、Jackson@JsonIncludeアノテーションを使用して行うことができます。

最新バージョンの javadoc (現在は 2.4)によると、フィールド値が null または空の場合に、注釈付きプロパティを含めるかどうかを簡単な注釈で指定できます。

これJsonInclude.Include.ALWAYSは、遅延ロードされていない値が null であっても、Jackson にはプロパティが含まれていることを意味します。

空または null 値を含めないように指定すると、JSON 応答のサイズを大幅に削減でき、すべての利点が含まれます。

この動作を変更する場合は、クラス レベルまたは単一のプロパティ/getterMethod レベルで注釈を追加できます。

空の場合に含めたくないフィールドに次の注釈を追加してみてください。

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
private List<Genre> genre;
于 2014-09-29T09:49:37.810 に答える
1

これは、遅延読み込みに関する既知の問題に関連している可能性があります。

私は jackson-datatype-hibernate を使用しませんが、同じ問題を解決するために私が行ったことは、Hibernate オブジェクトを直接シリアル化する代わりに、DTO を使用して永続的なコレクションを把握することです。Dozer のようなツールは、それを手助けしてくれます。あるいは、このようなマッピングを行うために私が書いた小さなユーティリティがあります。

DTO がどのように見えるかを試してみたい場合は、アンロードされた永続コレクションを、books.setGenre(new ArrayList<>()); のような通常の空のコレクションに置き換えることができます。残念ながら、遅延ロードされたオブジェクトがロードされたかどうかを確認する方法がわかりません。そのため、この再割り当てを自動的に行うことはできません。永続的なコレクションを置き換える場所は、ケースバイケースで決定する必要があります。

于 2014-09-18T11:56:47.957 に答える