2017-01-18 14 views
0

オブジェクトのJSONシリアライズに問題があります。オブジェクトが(私は「それをデバッグし、すべてのデータがあるVEのが、それがあるべきとして、それはシリアル化されません)が正しく構築されています。Java SpringでJSONに複数のOneToManyコレクションをシリアライズ

Studentクラス

public class Student extends AbstractUser { 

    ... 

    @OneToMany(mappedBy = "student", fetch = FetchType.EAGER, targetEntity = ActivityAttendance.class, cascade = CascadeType.ALL) 
    @Fetch(value = FetchMode.SUBSELECT) 
    private List<ActivityAttendance> attendances; 

    @OneToMany(mappedBy = "student", fetch = FetchType.EAGER, targetEntity = ActivityGrade.class, cascade = CascadeType.ALL) 
    @Fetch(value = FetchMode.SUBSELECT) 
    private List<ActivityGrade> grades; 

    ... 
} 

カスタム学生シリアライザは(使用しますActivityAttendance、無限再帰を除去するためのActivityGradeクラス)

ここ
public class CustomStudentSerializer extends StdSerializer<Student> { 

... 

@Override 
public void serialize(
     Student student, 
     JsonGenerator generator, 
     SerializerProvider provider) 
     throws IOException, JsonProcessingException { 

     ... 
     student.setAttendances(null); 
     student.setGrades(null); 
     ... 

     generator.writeObject(student); 
    } 
} 

によって私はACTIVに含まれる生徒のプロパティの出席/グレードを削除しますActivityAttendance、ActivityGradeオブジェクト。

ただし、JSON出力は、2つのコレクションのうちの1つのみの結果を常に返します。成績欄にはオブジェクトのリストも含める必要がありますが、常にnullを返します。

{ 
    "id": 1, 
    "firstName": "test", 
    "lastName": "test", 
    "email": "[email protected]", 
    "attendances": [ 
    { 
     "id": {}, 
     "student": { 
     ... 
     }, 
     "activity": { 
     ... 
     } 
    } 
    ], 
    "grades": null 
} 

要素を表示するには、グレードフィールドも欲しいです。コントローラでは、オブジェクトはすべてのデータを保持しています。

出席者フィールドを削除すると、成績が正しく表示されます。どのような原因があり、どのように解決できるかご存じですか?ありがとうございました。

答えて

0

DTOsを使用すると、無限再帰を避けることができます。基本的にはDTOは同じフィールド(idなし)を持ち、Jacksonはあなたのためにシリアライズしてください。あなたがちょうどメソッドを実装して、あなたのObjectControllerを経由して返す
あなたEntityたりEntity
例(ObjectMapper付きまたはgetters & settersEntityDTOへの変換Controller

@GetMapping 
ResponseEntity getStudent(@PathParam("firstName")String firstName){ 
    studentRepository.findStudentByFirstName(firstName).toDTO(); 
} 

URLがlocalhost:8080/students/firstName

のようになります。私はそれを自分で試しても問題はなかった2 lists

+0

私はModelMapperを使用してStudentにStudentをマッピングし、今度はそれを正常に動作させます。私はまだそれがなぜこのように動作するのか理解していません(アノテーションなしではほとんど同じオブジェクトなので)。しかし良い回避策です。ありがとう。 –

+0

うれしかったです。それを覚えておいてください。 'GET'や' POST'で 'Entity'を返すべきではありません。私の意見では、これは正しい方法であり、よりクリーンで簡単です。 –

関連する問題