2015-04-28 3 views
2

Сегодня я узнал один учебник, в котором автор объяснил, что объединение hibernate одно-ко многим/много-одному. Я не хочу писать здесь весь его код. Таким образом, я пытаюсь сосредоточиться на главной ...hibernate fetch lazy: Initialize() или HQL

У нас есть две сущности: "Team" и "игрока"

В коде мы имеем:

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

и

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

Главное, что меня интересует, это тип извлечения. Итак, мы ввели одну команду и некоторые игроков которые относятся к этому team. Моего класса DAO отмечен

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

А теперь я хочу, чтобы загрузить команды объекта из базы данных с заполненной коллекцией игроков.

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

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

В результате я получу LazyInitializationException. Это, очевидно, ...

Мы можем решить эту проблему:

Hibernate.initialize(team.getPlayers()); 

Или мы можем можете загрузить коллекцию игроков, использующих HQL. Я имею в виду:

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

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

Правильно ли это решение? И какой из них я должен использовать в реальном развитии?

И еще один вопрос. После того, как я инициализировал сбор игроков (независимо от того, какие из решений я использовал), я могу получить один из них. Хорошо, и в поле «player» entity команда будет инициализирована. Зачем? И эта команда будет с коллекцией заполненного игрока ... у нас есть круговые зависимости ... Это нормально?

+0

Вы закрыли сеанс Hibernate после 'sessionFactory.getCurrentSession().get (команда, id); 'line? сеанс все еще жив? –

+0

Я использую Spring, и я надеюсь, что Spring framework позаботится о закрытии сессии. Или я ошибаюсь? – Vadim

+0

Я не знаю, какую конфигурацию пружины вы использовали. но в соответствии с моим пониманием для команды team.getPlayers(); 'call, сеанс может закрыться, а командный объект отделился от сеанса. Это может быть причиной этой ошибки. Если вы попытаетесь выполнить ленивую загрузку с отдельного объекта, вы получите такую ​​ошибку. –

ответ

2

LazyInitializationException возникает, когда сеанс закрыт, и вы пытаетесь загрузить ленивый объект из отдельного объекта. Здесь команда - отдельный объект (поскольку сеанс мог быть закрыт перед этим вызовом) и пытается загрузить игроков ленивого объекта.

И о том, какой подход необходимо использовать для такого рода проблем, это зависит от ваших требований. если вы вызываете Hibernate.initialize для каждого прокси-сервера, каждый вызов будет генерировать один запрос.

И ниже вы используете сустав: -

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

это потребует только один запрос, я думаю, вы должны использовать этот подход, если запрос к много данных.

Для получения дополнительной информации см. this link.

Смежные вопросы