xNeyte
xNeyte

Reputation: 622

Hibernate, can't get data from relations

Using Hibernate in my web application. The database I'm using is :

User        Groupe      Groupes_Menus    Menu
UserID      GroupeID    GroupeID         MenuID
GroupeID                MenuID
Login

I'm trying to get all menus corresponding to one login. I got 3 java classes :

User Groupe and Menu

User mapping :

@Id
@Column(name="USERID", nullable = false)
private int userID;

@Column(name = "LOGIN", length = 8, nullable = false)
private String login;

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "GroupeID")
private Groupe groupe;

Groupe mapping :

@Id
@Column(name="GROUPEID", nullable = false)
private int groupeID;

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "GROUPES_MENUS", joinColumns = { @JoinColumn(name = "GROUPEID") }, inverseJoinColumns = { @JoinColumn(name = "MENUID") })
private Set<Menu> menus = new HashSet<Menu>(0);

Menu mapping :

@Id
@Column(name="MENUID", nullable = false)
private int menuID;

Error I get is :

failed to lazily initialize a collection of role: entity.Groupe.menus, no session or session was closed (through reference chain: entity.User["groupe"]->entity.Groupe["menus"]) 

Not sure what is wrong in my code or anything, really beginner with hibernate

Upvotes: 1

Views: 70

Answers (2)

Ankur Singhal
Ankur Singhal

Reputation: 26067

@ManyToMany is Lazy be default.

If you try to call getter on this relation, outside the session/transaction, it will throw the error. Within the same session/transaction calling getter will not cause any issue.

To overcome this issue, we can go with two options here.

1.) Making @ManyToMany to Eager instead of Lazy

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)

** But this will always fetch eagerly, even if you do not require.

2.) Initialize in Transaction when needed.

 Hibernate.initialize(groupe.getMenus());

Upvotes: 1

Sergii Bishyr
Sergii Bishyr

Reputation: 8641

@ManyToMany reltation is Lazy be default. You cannot get it outside the session. Try to use JOIN FETCH in your query. Also, you it's possibe to make you relation EAGER by default:

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)

But this is bad from performance POV.

Upvotes: 0

Related Questions