views:

23

answers:

2

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?

Thanks

A: 

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 or EAGER 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.

Pascal Thivent
yes. the same thing happens. i can understand that it makes sense b/c hibernate needs to bring all the list objects for each list and it's an infinite loop. my question is if it's possible to limit the depth that hibernate brings objects (something like fetch_max_depth but for many-to-many).
Rafa
@Rafa Actually, I'd expect Hibernate to detect the cycle and do the appropriate thing (but I didn't take the time to test this). On the other hand, I can't say this loading eagerly both sides of a many-to-many looks like a good idea.
Pascal Thivent
A: 

Hibernate works ok when it tries to eagerly fetch everything it needs to. Modeling objects has to take hibernate into account so loops and stackoverflow exceptions won't occur.

What i did is removing one side of the relationship. You can decide if you want to remove that side or to leave it and define the other side as the owner. You'll also need to remove the eager fetching from that side.

It would be nice if hibernate could give a mechanism for defining the depth of fetching in many-to-many relationships.

Rafa

related questions