I have a question which I think should be pretty common but I can't find an answer.
I have 2 objects: Group and User. My classes look something like this:
class Group
{
@ManyToMany(fetch = FetchType.EAGER)
List<User> users;
}
class User
{
@ManyToMany(fetch = FetchType.EAGER)
List<Group> groups;
}
Now, when I try to get a User from the database it brings all its groups and all groups bring all its users and so on. Finally, I'm getting a stackoverflow exception.
How can I solve this issue and still have my bidirectional association and the ability to reach the objects in the lists?
The FetchType. LAZY tells Hibernate to only fetch the related entities from the database when you use the relationship. This is a good idea in general because there's no reason to select entities you don't need for your uses case. You can see an example of a lazily fetched relationship in the following code snippets.
LAZY: It fetches the child entities lazily i.e at the time of fetching parent entity it just fetches proxy(created by cglib or any other utility) of the child entities and when you access any property of child entity then it is actually fetched by hibernate. EAGER: it fetches the child entities along with parent.
By default, Hibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. These defaults make sense for most associations in the majority of applications.
Bidirectional association allows us to fetch details of dependent object from both side. In such case, we have the reference of two classes in each other. Let's take an example of Employee and Address, if Employee class has-a reference of Address and Address has a reference of Employee.
Do you get the same problem if you make one of the sides of your bidirectional assocation the owning side of the association using the mappedBy
attribute (that you should use anyway)? Like this:
@Entity public class Group {
...
@ManyToMany(fetch = FetchType.EAGER, mappedBy="groups")
List<User> users;
}
@Entity public class User {
...
@ManyToMany(fetch = FetchType.EAGER)
List<Group> groups;
}
Update: I can't find any evidence that using EAGER
fetching on both sides of a bidirectional association is forbidden and AFAIK, there is no mention of such a restriction in the Hibernate documentation and / or the JPA specification.
Actually, according to this comment from Emmanuel Bernard to a (somehow similar) issue:
LAZY
orEAGER
should be orthogonal to an infinite loop issue in the codebase. Hibernate knows how to handle cyclic graphs
For me, the above is pretty clear, Hibernate should be able to handle your mapping (as I mentioned in a comment) and I would be tempted to consider any contradictory behavior as a bug.
If you can provide a test case allowing to reproduce the problem, my suggestion would be to open an issue.
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