LazyInitializationException: could not initialize proxy - no



我有一个情况,我得到LazyInitialzationException在我的项目。它发生在这里:

if (study.getIbId().equals(actor.getRepository().getIbId())) {

actor变量为Account类型,Repository变量为Repository类型。Ibid为Long类型。Account和Repository来自hibernate。错误来自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)

缺少一些信息,例如如何管理会话和事务。异常只是告诉您,没有会话绑定到您的请求。

尽管如此,我会尽量给你指出一个好的方向。首先,您需要一个SessionFactory对象来管理会话。将它封装在单例模式中是一个很好的实践,因为hibernate会话不是线程安全的。

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();
}
}

现在你可以调用Session hSession = HibernateFactory.getInstance().getSession();

然后确保你的延迟加载在你定义的事务绑定内。

...
Session session = HibernateFactory.getInstance().getSession();
session.beginTransaction();
if (study.getIbId().equals(actor.getRepository().getIbId())) {
...
session.getTransaction().commit()
session.close();

一般来说,如果你只是获取数据,你不需要显式地打开事务,但这是一个很好的实践。如果需要,请记住在需要时提交和回滚。

还有关于什么是fetch和load的问题。参考:https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/performance.html

相关内容

最新更新