In this case it would fail on students, creating an infinite recursive loop through the reference chain. I can stop it with @JsonIgnoreProperty but I want this field to be serialized. I am serializing my object like so:

The only workaround I can think of is appending a string to the end of teacher while still ignoring the property but I am not sure if I will be able to read students as a JsonNode from the tree if I do this.

Where Mill and OtherPOJO are class with not much more than a couple of arrays and other primitives : pure POJOs.

It works fine both ways with Jackson and MongoJack (jackson serializer for MongoDb).

If you can't get away from the set than you have to understand properly what is the fundamental data structure in a set. This should help but you are probably already aware of that.

A way to work around this structure limitation would be to create non-dumb getters and setters. The main disadvantage behind this method is that you run one more for loop over all your elements every time you serialize or de-serialize. This might slightly reduce performance.

The getter is fairly simple :

public Student[] getStudents(){
return this.students.toArray();
}

And the setter is also pretty trivial :

public void setStudents(Student[] students){
this.students = new Set<Student>(); // Or anything that builds the right Set for you
for(int i = 0; i < students.length; i++){
this.students.add(students[i]);
}
}