有关于Gson“循环参考”的解决方案吗?

时间:2011-12-06 15:57:11

标签: java gson circular-reference

我发现很多关于Gson循环引用的文章,但我找不到一个优雅的解决方案。

据我所知,有些解决方案是:

  • 将导致循环引用的属性设置为“transient”。
  • 使用某些注释排除该属性。

但作为一般性问题,是否有一些解决问题的共同策略?

3 个答案:

答案 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:创建自己的类型适配器