hibernate:LazyInitializationException:无法初始化代理

Pik*_*iko 70 hibernate initialization lazy-evaluation

这是让我感到困惑的一个.我正在尝试实现一个基本的Hibernate DAO结构,但是遇到了问题.

这是基本代码:

int startingCount = sfdao.count();
sfdao.create( sf );
SecurityFiling sf2 = sfdao.read( sf.getId() );
sfdao.delete( sf );
int endingCount = sfdao.count();

assertTrue( startingCount == endingCount );
assertTrue( sf.getId().longValue() == sf2.getId().longValue() );
assertTrue( sf.getSfSubmissionType().equals( sf2.getSfSubmissionType() ) );
assertTrue( sf.getSfTransactionNumber().equals( sf2.getSfTransactionNumber() ) );
Run Code Online (Sandbox Code Playgroud)

它在第三个assertTrue上失败,它试图将sf中的值与sf2中的相应值进行比较.这是例外:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:86)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:140)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
    at com.freightgate.domain.SecurityFiling_$$_javassist_7.getSfSubmissionType(SecurityFiling_$$_javassist_7.java)
    at com.freightgate.dao.SecurityFilingTest.test(SecurityFilingTest.java:73)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
Run Code Online (Sandbox Code Playgroud)

pak*_*ore 68

问题是您正在尝试访问已分离的对象中的集合.在将集合访问到当前会话之前,需要重新附加对象.你可以做到这一点

session.update(object);
Run Code Online (Sandbox Code Playgroud)

使用lazy=false不是一个好的解决方案,因为你丢弃了休眠的懒惰初始化功能.何时lazy=false,在请求对象的同时将集合加载到内存中.这意味着如果我们有一个包含1000个项目的集合,它们都将被加载到内存中,尽管我们将要访问它们.这不好.

请阅读这篇文章,它解释了问题,可能的解决方案以及为什么以这种方式实现.另外,要了解会话和事务,您必须阅读其他文章.


dig*_*tum 14

这通常意味着拥有的Hibernate会话已经关闭.您可以执行以下操作之一来修复它:

  1. 无论哪个对象创建此问题,请使用 HibernateTemplate.initialize(object name)
  2. 使用lazy=false您的HBM文件.

  • @Victor lazy = false与渴望相同。当我们选择使用紧急加载关联时,每次加载实体时,即使我们不询问也不使用它,所有“紧急关联”也会加载。 (2认同)

小智 11

看我的文章.我遇到了同样的问题--LazyInitializationException - 这里是我最终提出的答案:
http://community.jboss.org/wiki/LazyInitializationExceptionovercome
设置lazy = false不是答案 - 它可以一次性加载所有内容,这就是不一定好.示例:
1记录表A引用:
5记录表B引用:
25记录表C引用:
125记录表D
...
等等这只是可能出错的一个示例.
--Tim Sabin


小智 7

如果您正在使用带有JPA注释的hibernate,那么这将非常有用.在您的服务类中,应该有一个带有@PersistenceContext的实体管理器的setter.将其更改为@PersistenceContext(type = PersistenceContextType.EXTENDED).然后你可以在任何地方访问懒惰的财产.