Vadym
Vadym

Reputation: 417

hibernate fetch lazy: Initialize() or HQL

Today I learned one tutorial where author explained hibernate association one-to-many / many-to-one. I don't want to write all his code here. So, I try to focus on main...

We have two entities: "Team" and "Player"

In code we have:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="team_id")
private Team team;

and

@OneToMany(mappedBy="team", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Player> players;

The main thing which I interested is type of fetch. So, we inserted one team and some players which are belongs to this team. My DAO class marked with

@Transactional(propagation = Propagation.REQUIRED, readOnly = false)

And now I want to load team entity from database with filled collection of players.

Team team = new Team();
sessionFactory.getCurrentSession().get(team, id);

//and after somewhere in code
team.getPlayers();

At result I will get LazyInitializationException. It's obviously...

We can resolve this problem:

Hibernate.initialize(team.getPlayers());

Or we can can load collection of players using HQL. I mean:

Query query = currentSession().createQuery("from Player p where p.team.id =:id");
query.setParameter("id",key);

team.setPlayers(new HashSet(query.list()));

Is it right solutions? And which of them I should use in real development?

And one more question. After I initialized collection of players (no matter which of solutions I used) I can get one of them. Ok, And in "player" entity field Team will initialize. Why? And this team will be with filled player's collection... we have circular dependencies... This is normal?

Upvotes: 2

Views: 2469

Answers (1)

Anchit Pancholi
Anchit Pancholi

Reputation: 1214

LazyInitializationException comes when session is closed and you try to load lazy object from detached Object. Here team is detached object (As session might have closed before this call) and trying to load lazy object players.

And About which approach need to use for this kind of problem, it is up to your requirement. if you call Hibernate.initialize on each proxy, Each call will generate one query.

And with below you are using joint :-

Query query = currentSession().createQuery("from Player p where p.team.id =:id");

this will only require one query, i think you should use this approach if you query a lots of data.

For more information take a look at this link.

Upvotes: 2

Related Questions