简体   繁体   中英

Is there a solution about Gson "circular reference"?

I have found many articles about the circular reference with Gson, but I can't find an elegant solution.

As I know, some solutions is:

  • Set the property that caused circular reference as "transient".
  • exclude the property with some annotation.

But as a general question, is there some common strategy to solve the problem?

As far as I know there is no automated solution for circular references in Gson. The only JSON-producing library I know of that handles circular references automatically is XStream (with Jettison backend).

EDIT: Jackson also supports handling of circular references with @JsonIdentityInfo annotation; so while not automatic (you do need to mark references that need Object Id handling), it does allow solving most cases.

Since Gson doesn't properly handle circular references, and in some cases you may need to call the parent entity from its child, you can do this. Say we have:

@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;
}

and

@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;
    }

In this case, you may need to get a PostgresServer reference from a PostgresTable entity. So, instead of excluding PostgresServer from serialization, you simply set its List of tables to null . For example:

//Assuming a List<PostgresTable>...
postgresTables.forEach(postgresTable -> postgresTable.getServer().setTables(null));

This is how i solve circular references with Gson. Hope that helps someone.

I am looking into this issue as well. Gson does not provide a default solution so far. What you can do is:

Option 1: Create an exclusion strategy which implements ExclusionStrategy to exclude the class and/or field in the circular reference;

Option 2: Use annotations to mark the field to be transient to avoid serialization;

Option 3: Create your own type adapter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM