Ok, so I have a very simple set of Java POJOs in my spring application.
Here is my person class :
@Document(collection="people")
public class Person {
// Data.
@Id
private ObjectId Id;
@DBRef
private List<Entity> entities;
/* Getters and setters removed to keep this question simple. */
}
And, here is my entity class.
@Document(collection = "entities")
public class Entity {
@Id
private ObjectId Id;
@DBRef
private List<Person> people;
/* Getters and setters removed to keep question simple. */
}
Now, in my spec, "Person" and "Entity" have a Many-Many relationship. A Person can be registered to lots of Entities, and the reverse is true, too.
Now, for some reason, when I try and persist these two, into each other's lists, I get this weird error I have never seen :
2017-05-17 23:37:51.966 ERROR 29918 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion (StackOverflowError) (through reference chain: restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]
... This continues until the stack overflows. Sorry it is all on one line, wasn't sure how to fix that on this site... it is cut straight from my terminal.
What did I do wrong? I have been doing pretty well so far at learning this stack, but I just can't see what is wrong here.
Yes this case can occur! Consider you have:
person1 = {"entities" : ["entity1", "entity2"]}
entity1 = {"persons" : ["person1", "person2"]}
So using your above configuration, when spring tries to load "person1", it will load its related "entities(entity1 & entity2)" as well. Now when spring tries to load "entity1", it will again have to load "person1" and so, which definitely leads to Circular dependency/ recursion!
restServer.dto.Person["entity"]->restServer.dto.Entity["people"]->java.util.ArrayList[0]->restServer.dto.Person["entity"]->restServer.dto.Entity["people"]...
So you can handle this by many ways:
@Document(collection="people")
public class Person {
// Data.
@Id
private ObjectId Id;
@DBRef(lazy = true)
private List<Entity> entities;
/* Getters and setters removed to keep this question simple. */
}
@Document(collection = "entities")
public class Entity {
@Id
private ObjectId Id;
@DBRef(lazy = true)
private List<Person> people;
/* Getters and setters removed to keep question simple. */
}
lazy = true will prevent Spring from loading un-necessary entities unless you need it(which you can load it by making an explicit call)
@Document(collection="people")
public class Person {
// Data.
@Id
private ObjectId Id;
private List<Entity> entities;
/* Getters and setters removed to keep this question simple. */
}
@Document(collection = "entities")
public class Entity {
@Id
private ObjectId Id;
private List<Person> people;
/* Getters and setters removed to keep question simple. */
}
But it totally depends on your requirements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With