我发现很多关于Gson循环引用的文章,但我找不到一个优雅的解决方案。
据我所知,有些解决方案是:
但作为一般性问题,是否有一些解决问题的共同策略?
答案 0 :(得分:2)
据我所知,Gson中没有循环引用的自动化解决方案。 我所知道的唯一一个自动处理循环引用的JSON生成库是XStream(使用Jettison后端)。
编辑:杰克逊还支持使用@JsonIdentityInfo
注释处理循环引用;所以虽然不是自动的(你需要标记需要对象ID处理的引用),但它确实允许解决大多数情况。
答案 1 :(得分:0)
由于Gson无法正确处理循环引用,并且在某些情况下,您可能需要从其子对象调用父实体,因此可以执行此操作。说我们有:
@Entity
@Table(name = "servers_postgres")
public class PostgresServer implements Serializable {
public PostgresServer() {
this.tables = new ArrayList<>();
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_server")
private Integer serverId;
@OneToMany(orphanRemoval = true, mappedBy = "server", fetch = FetchType.EAGER)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
private List<PostgresTable> tables;
@Column(length = 250)
private String serverAddress;
@Column(length = 250)
private String name;
}
和
@Entity
@Table(name = "postgres_tables")
public class PostgresTable implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_table")
private Integer tableId;
@Column(length = 250)
private String name;
@ManyToOne()
@JoinColumn(name = "id_server", foreignKey = @ForeignKey(name = "fk_postgres_tables"))
private PostgresServer server;
}
在这种情况下,您可能需要从PostgresTable实体获取PostgresServer引用。因此,只需将 PostgresServer 排除在序列化之外,只需将其“表列表”设置为null 即可。例如:
//Assuming a List<PostgresTable>...
postgresTables.forEach(postgresTable -> postgresTable.getServer().setTables(null));
这就是我用Gson解决循环引用的方式。希望能对某人有所帮助。
答案 2 :(得分:-1)
我也在调查这个问题。到目前为止,Gson尚未提供默认解决方案。您可以做的是:
选项1:创建一个实施ExclusionStrategy的排除策略,以排除循环引用中的类和/或字段;
选项2:使用注释将字段标记为瞬态,以避免序列化;
选项3:创建自己的类型适配器