GSONを使用してJSONでJavaクラスを変換する場合、循環参照と無限ループの原因となるフィールドを回避できます。JSONに表示するフィールドに注釈@Exposeを配置するだけで、アノテーション@ExposeはJSONに表示されません。
循環参照は、たとえば、クラスUserをクラスRouteのフィールドroutesでシリアル化しようとし、クラスRouteにクラスUserのフィールドuserがある場合、GSONはクラスUserをシリアル化しようとし、ルートをシリアル化しようとすると、クラスRouteをシリアル化し、クラスRouteでフィールドuserをシリアル化しようとし、クラスUserを再度シリアル化しようとすると、無限ループを引き起こす循環参照があります。言及したクラスUserとRouteを示します。
import com.google.gson.annotations.Expose;
クラスユーザー
@Entity
@Table(name = "user")
public class User {
@Column(name = "name", nullable = false)
@Expose
private String name;
@OneToMany(mappedBy = "user", fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
private Set<Route> routes;
@ManyToMany(fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinTable(name = "like_", joinColumns = @JoinColumn(name = "id_user"),
inverseJoinColumns = @JoinColumn(name = "id_route"),
foreignKey = @ForeignKey(name = ""),
inverseForeignKey = @ForeignKey(name = ""))
private Set<Route> likes;
クラスルート
@Entity
@Table(name = "route")
public class Route {
@ManyToOne()
@JoinColumn(nullable = false, name = "id_user", foreignKey =
@ForeignKey(name = "c"))
private User user;
不定詞のループを回避するために、GSONを提供するアノテーション@Exposeを使用します。
GSONでクラスUserをシリアル化した結果をJSON形式で表示します。
{
"name": "ignacio"
}
フィールドルートなどはJSON形式ではなく、フィールド名のみが存在することがわかります。このため、循環参照は避けられます。
これを使用する場合は、特定の方法でオブジェクトGSONを作成する必要があります。
Gson converterJavaToJson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
最後に、作成された会話者GSONを使用して、休止状態のユーザーのモデルのJavaクラスを変換します。
User user = createUserWithHibernate();
String json = converterJavaToJson.toJson(user);