#java #hibernate #hbm
Вопрос:
У меня есть случай, когда я получаю исключение LazyInitialzationException в своем проекте. Это происходит здесь:
if (study.getIbId().equals(actor.getRepository().getIbId())) {
actor
переменная — это тип Account
и Repository
есть тип Repository
. Ibid
Длинный тип. Учетная запись и репозиторий выходят из режима гибернации. Ошибка происходит из getIbId()
, что означает Repository
, что объект не был увлажнен(?). Вот Account.hbm.xml файл:
Учетная запись:
...
</many-to-one>
<many-to-one cascade="all" class="com.accelarad.data.mapping.account.Repository" column="REPOSITORY_ID" lazy="proxy" name="repository" unique="true">
...
Как видите, lazy=proxy
собственность есть. Когда я изменяю его на lazy=false
, я больше не получаю исключение LazyInitializationException.
Из того, что я понимаю, если lazy=false, он охотно извлекается, поэтому это не эффективно. Есть ли способ сохранить lazy=proxy
и загрузить Repository
его ? Что значит lazy=${something}
«и fetch=${something}
«?
ИЗМЕНИТЬ: журнал ошибок:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:147)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:260)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:73)
at com.accelarad.data.mapping.account.Repository_$_jvst9a5_5d.getIbId(Repository_$_jvst9a5_5d.java)
at com.accelarad.smr.widgets.service.impl.ShareImageServiceImpl.isNetworkStudy(ShareImageServiceImpl.java:265)
at com.accelarad.smr.widgets.ShareImageController.autoCompleteAccount(ShareImageController.java:231)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
Комментарии:
1. не могли бы вы добавить журналы ошибок
2. Где вы открываете сессию?
Ответ №1:
Отсутствует некоторая информация, например, о том, как вы управляете сеансом и транзакциями. Исключение говорит вам только о том, что сеанс не привязан к вашему запросу.
Тем не менее я постараюсь указать вам хорошее направление. Сначала вам понадобится объект SessionFactory для управления вашими сеансами. Рекомендуется инкапсулировать его в одноэлементный шаблон, поскольку сеансы гибернации не являются потокобезопасными.
public class HibernateFactory {
private SessionFactory factory;
private static HibernateFactory hf;
private HibernateFactory() throws HibernateException {
/* different versions of hibernate has different ways to build a session factory */
factory = new Configuration().configure().buildSessionFactory();
}
/* synchronized so there is no multi use problems */
synchronized public static HibernateFactory getInstance() throws HibernateException {
if (hf == null) {
hf = new HibernateFactory();
}
return hf;
}
/* will open a session and keep it open until closed manually */
public Session getSession() throws HibernateException {
return this.factory.openSession();
}
/* will open a session and close it automatically after transaction */
public Session getCurrentSession() throws HibernateException {
return this.factory.getCurrentSession();
}
public void finalize() throws HibernateException {
this.factory.close();
}
}
Итак, теперь вы можете вызвать сеанс hSession = HibernateFactory.getInstance().getSession();
Затем убедитесь, что ваша ленивая нагрузка находится внутри определенной вами транзакции.
...
Session session = HibernateFactory.getInstance().getSession();
session.beginTransaction();
if (study.getIbId().equals(actor.getRepository().getIbId())) {
...
session.getTransaction().commit()
session.close();
Как правило, вам не нужно будет явно открывать транзакцию, если вы просто извлекаете данные, но в любом случае это хорошая практика. Если вы это сделаете, не забудьте зафиксировать и откатить, если это необходимо.
Также для вашего другого вопроса о том, что такое извлечение и загрузка. См.: https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/performance.html