Better handling of circular reference serialization in Java
Given 2 generic POJOs that include references to each other such as:
package com.example;
public class Course {
Student _student;
public void setStudent(Student student) {
_student = student;
}
public Student getStudent() {
return _student;
}
}
package com.example;
public class Student {
private Course _course;
public void setCourse(Course course) {
_course = course;
}
public Course getCourse() {
return _course;
}
}
It would be useful to have a configuration mechanism to prevent Maximum serialization depth exceeded exceptions from being thrown.
package com.example;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
public class App {
public static void main(final String[] args) {
CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(),
pojoCodecRegistry);
MongoClientSettings clientSettings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("mongodb://localhost:27017"))
.codecRegistry(codecRegistry)
.build();
MongoClient mongoClient = MongoClients.create(clientSettings);
MongoDatabase database = mongoClient.getDatabase("test");
MongoCollection<Student> students = database.getCollection("students", Student.class);
MongoCollection<Course> courses = database.getCollection("courses", Course.class);
students.deleteMany(new Document());
courses.deleteMany(new Document());
Student student = new Student();
Course course = new Course();
student.setCourse(course);
course.setStudent(student);
students.insertOne(student);
courses.insertOne(course);
System.out.println(students.find(new Document()).first());
System.out.println(courses.find(new Document()).first());
}
}
The above would result in the following:
Exception in thread "main" org.bson.BsonSerializationException: Maximum serialization depth exceeded (does the object being
serialized have a circular reference?).
at org.bson.AbstractBsonWriter.writeStartDocument(AbstractBsonWriter.java:285)
at com.mongodb.internal.connection.BsonWriterDecorator.writeStartDocument(BsonWriterDecorator.java:48)
at com.mongodb.internal.connection.LevelCountingBsonWriter.writeStartDocument(LevelCountingBsonWriter.java:42)
at com.mongodb.internal.connection.IdHoldingBsonWriter.writeStartDocument(IdHoldingBsonWriter.java:78)
at org.bson.codecs.pojo.PojoCodecImpl.encode(PojoCodecImpl.java:94)
at org.bson.codecs.pojo.LazyPojoCodec.encode(LazyPojoCodec.java:47)
at org.bson.codecs.EncoderContext.encodeWithChildContext(EncoderContext.java:91)
at org.bson.codecs.pojo.PojoCodecImpl.encodeValue(PojoCodecImpl.java:181)
at org.bson.codecs.pojo.PojoCodecImpl.encodeProperty(PojoCodecImpl.java:169)
at org.bson.codecs.pojo.PojoCodecImpl.encode(PojoCodecImpl.java:106)
at org.bson.codecs.pojo.LazyPojoCodec.encode(LazyPojoCodec.java:47)
at org.bson.codecs.EncoderContext.encodeWithChildContext(EncoderContext.java:91)
....... etc
2
votes
AdminAlex
(Admin, MongoDB)
shared this idea