1

I have two classes that reference each other. When I try to serialize the classes to Json I get a circular reference error. Can any one tell me how to correct this?

I have a Folder class with a list of passwords:

public class Folder {

    private List<Password> items = new ArrayList<>();
    private String name;

    public Folder(String name) {
        this.name = name;
    }

    public void add(Password password) {
        items.add(password);
    }

    public List<Password> getItems() {
        return items;
    }

    public void setItems(List<Password> items) {
        this.items = items;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }       
}

Then I have a Password class that references back to the Folder class:

public class Password {

    private String name;
    private Folder mFolder;

    public Password(String name, Folder folder) {
        this.name = name;
        folder.add(this);
        mFolder = folder;       
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Folder getmFolder() {
        return mFolder;
    }

    public void setmFolder(Folder mFolder) {
        this.mFolder = mFolder;
    }    
}

and finally the Main class:

public class Main {

    public static void main(String[] args) throws IOException {

        Password password = new Password("Password", new Folder("Folder"));

        Jsonb jsonb = JsonbBuilder.create();        
        try (Writer writer = new StringWriter()) {          
            jsonb.toJson(password, writer);
            System.out.println(writer.toString());
        }
    }    
}

The get the following exception:

at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:60)
    at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serializerCaptor(AbstractContainerSerializer.java:91)
    at org.eclipse.yasson.internal.serializer.CollectionSerializer.serializeInternal(CollectionSerializer.java:76)
    at org.eclipse.yasson.internal.serializer.CollectionSerializer.serializeInternal(CollectionSerializer.java:35)
    at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:60)
    at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serializerCaptor(AbstractContainerSerializer.java:91)
    at org.eclipse.yasson.internal.serializer.ObjectSerializer.marshallProperty(ObjectSerializer.java:92)
    at org.eclipse.yasson.internal.serializer.ObjectSerializer.serializeInternal(ObjectSerializer.java:59)
Hendré
  • 262
  • 10
  • 27

2 Answers2

4

In either Password or Folder, you need to remove their reference (in serialisation) to each other. You can use @JsonbTransient to the field you don't want to be serialised in JSON.

(docs: http://json-b.net/docs/user-guide.html#ignoring-properties)

Example: Password class approach

@JsonbTransient
private Folder mFolder;

Example: Folder class approach

@JsonbTransient
private List<Password> items = new ArrayList<>();

It's up to you now which class will not show the reference to another class. Also, see this

sweet suman
  • 1,031
  • 8
  • 18
-1

This issue occur when two classes refer to each other. you can use GSONBuilder to get custom gson object using setExclusionStrategies method

GSON gsonObject = new GsonBuilder()
    .setExclusionStrategies(new ExclusionStrategy() {
     /** boolean method shouldSkipClass(Class<?> clz) */
     /** boolean method shouldSkipField(FieldAttributes field) */
});
DHARMENDRA SINGH
  • 607
  • 5
  • 21