我正在尝试使用Spring MVC创建一个Web应用程序,将Hibernate作为其ORM层.但是,由于我对这两个框架缺乏经验,我正在努力.
以下代码将正确显示我正在查找的所有记录,但仍将堆栈跟踪放入我的日志中.我无法找到有关集成Hibernate和SpringMVC的详细文档(我查看了springsource.org并阅读了关于interweb的各种文章).谁能指出我在这里做错了什么?
请注意,我花了一些时间试图在互联网上找到答案,包括查看这个问题.遗憾的是没有帮助.
我还应该注意,此应用程序的ORM部分已在独立的Java应用程序中使用和测试,没有任何问题.所以我认为Spring MVC和Hibernate的集成导致了这个问题.
这是具有着名的延迟初始化问题的堆栈跟踪(截断);
2009-03-10 12:14:50,353 [http-8084-6] ERROR org.hibernate.LazyInitializationException.(LazyInitializationException.java:19) - could not initialize proxy - no Session org.hibernate.LazyInitializationException: could not initialize proxy - no Session at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57) at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111) at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150) at com.generic.orm.generated.SearchRule$$EnhancerByCGLIB$$92abaed6.toString( ) at java.lang.String.valueOf(String.java:2827) at java.lang.StringBuffer.append(StringBuffer.java:219) at org.apache.commons.lang.builder.ToStringStyle.appendDetail(ToStringStyle.java:578) at org.apache.commons.lang.builder.ToStringStyle.appendInternal(ToStringStyle.java:542) at org.apache.commons.lang.builder.ToStringStyle.append(ToStringStyle.java:428) at org.apache.commons.lang.builder.ToStringBuilder.append(ToStringBuilder.java:840) at org.apache.commons.lang.builder.ReflectionToStringBuilder.appendFieldsIn(ReflectionToStringBuilder.java:606) .....
这是我的网页控制器的代码;
private ListgetReports() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); List reports = session.createCriteria(Report.class).list(); Hibernate.initialize(reports); session.getTransaction().commit(); return reports; }
使用此显示html在网页上使用哪个;
注意:我添加了report.searchRule.name以测试是否可以获取报表对象中的对象.它显示很好.
在我的applicationContext.xml中;
classpath:hibernate.cfg.xml ${hibernate.dialect}
以下是ORM映射,以防万一;
hibernate.cfg.xml(根据要求)
com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc:sqlserver:// thread false
来自report.hbm.xml
jtgameover.. 25
我刚刚完成了这项LazyInitialization马拉松比赛.
核心问题是你试图在生命周期之外Session
,即在Spring MVC的Web视图中访问一个hibernate管理的实体.就我而言,这是一个List<>
@OneToMany
关联,默认情况下会延迟加载.
有几种不同的方法 - 马克提到过一种方法,你在懒惰的关联上进行"虚拟"迭代.您还可以通过配置(类范围)(在JPA中@Fetch(value = FetchType.EAGER)
)或更具体地通过HQL 强制进行预先加载.但如果您的懒惰关联,Lists
这将证明更有问题.
我找到的最干净的解决方案是使用Spring OpenEntityManagerInViewFilter
(有一个OpenSessionInViewFilter
用于Hibernate的) - 一个简单的servlet过滤器,你可以使用它web.xml
(在你的其他servlet过滤器之前),Spring将自动创建一个线程安全,事务感知的Session
每个HTTP - 请求.没有更多LazyInitializationException
!
我刚刚完成了这项LazyInitialization马拉松比赛.
核心问题是你试图在生命周期之外Session
,即在Spring MVC的Web视图中访问一个hibernate管理的实体.就我而言,这是一个List<>
@OneToMany
关联,默认情况下会延迟加载.
有几种不同的方法 - 马克提到过一种方法,你在懒惰的关联上进行"虚拟"迭代.您还可以通过配置(类范围)(在JPA中@Fetch(value = FetchType.EAGER)
)或更具体地通过HQL 强制进行预先加载.但如果您的懒惰关联,Lists
这将证明更有问题.
我找到的最干净的解决方案是使用Spring OpenEntityManagerInViewFilter
(有一个OpenSessionInViewFilter
用于Hibernate的) - 一个简单的servlet过滤器,你可以使用它web.xml
(在你的其他servlet过滤器之前),Spring将自动创建一个线程安全,事务感知的Session
每个HTTP - 请求.没有更多LazyInitializationException
!
我只是在猜测,但是从堆栈跟踪看来,似乎在SearchRule上调用了toString.SearchRule是否有任何可能尚未加载的子对象?如果SearchRule.toString尝试获取未初始化的子对象的值,可能导致LazyInitializationException.