Есть ли решение по поводу "круговой ссылки" в Gson? - PullRequest
7 голосов
/ 06 декабря 2011

Я нашел много статей о циклической ссылке с Gson, но не могу найти элегантного решения.

Как я знаю, некоторые решения:

  • Установитесвойство, которое вызвало циклическую ссылку как «переходный процесс».
  • исключает свойство с некоторой аннотацией.

Но, как правило, существует ли общая стратегия для решения проблемы?*

Ответы [ 2 ]

2 голосов
/ 09 декабря 2011

Насколько я знаю, в Gson нет автоматизированного решения для циклических ссылок. Единственная известная мне JSON-производящая библиотека, которая обрабатывает циклические ссылки автоматически: XStream (с бэкендом Jettison).

РЕДАКТИРОВАТЬ: Джексон также поддерживает обработку циклических ссылок с @JsonIdentityInfo аннотацией; поэтому, хотя он и не автоматический (вам нужно помечать ссылки, для которых требуется обработка Object Id), он позволяет решать большинство случаев.

0 голосов
/ 19 ноября 2018

Поскольку 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;
    }

В этом случае вам может потребоваться получить ссылку на PostgresServer от объекта PostgresTable.Таким образом, вместо исключения PostgresServer из сериализации, вы просто устанавливаете для его списка таблиц значение null .Например:

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

Вот так я решаю круговые ссылки с помощью Gson.Надеюсь, это кому-нибудь поможет.

...