我正在做一个结合struts+spring+hibernate的项目。Hibernate 是我最喜欢的一个框架,但我遇到了延迟初始化异常的问题。我必须解决这个问题,但我不想放弃的是
- 我不能从我的项目中释放 DTO,这有助于在层之间进行通信。
- 我不想将持久性对象访问到服务层。
- 我不想丢失将 Persistence 对象转换为数据传输对象的 Utility 类。
这是我已经完成的编码实现。我在服务层调用这个方法
sectionsservice.getAllSections();
DAO 实现是这样的
public List<SectionsTO> getAllSections() {
List<SectionsTO> sectionsto_list=new ArrayList<SectionsTO>();
List<Sections> sections_list=htemp.loadAll(Sections.class);
try {
SessionFactory factory=HibernateUtil.getSessionFactory();
Session session=factory.openSession();
Transaction tx=session.beginTransaction();
Query qry=session.createQuery("from Sections sections");
List list=qry.list();
Iterator it=list.iterator();
while(it.hasNext()) {
Sections sections=(Sections)it.next();
SectionsTO sectionsto=**PropertyUtil**.getSectionsTOFromSections(sections);
sectionsto_list.add(sectionsto);
}
tx.commit();
session.close();
factory.close();
}
catch(Exception e) {
e.printStackTrace();
}
return sectionsto_list;
}
这是 PropertyUtil 类的实现
public static SectionsTO getSectionsTOFromSections(Sections sections) {
SectionsTO sectionsto=new SectionsTO();
sectionsto.setSection_id(sections.getSection_id());
sectionsto.setSection_name(sections.getSection_name());
sectionsto.setSection_desc(sections.getSection_desc());
sectionsto.setThreads(sections.getThreads());
sectionsto.setPosts(sections.getPosts());
sectionsto.setLast_post(sections.getLast_post());
sectionsto.setLast_post_by(PropertyUtil.getMembersTOFromMembers(sections.getLast_post_by()));
sectionsto.setQuestion_id(sections.getQuestion_id());
Set<Questions> questions_set=sections.getQuestions_set();
Set<QuestionsTO> questions_set_to=new HashSet<QuestionsTO>();
Iterator<Questions> it=questions_set.iterator();
while(it.hasNext()) {
QuestionsTO questionsto=PropertyUtil.getQuestionsTOFromQuestions(it.next());
questions_set_to.add(questionsto);
}
return sectionsto;
}
这是我得到的错误的堆栈跟踪
SEVERE: Servlet.service() for servlet [action] in context with path [/TechForum] threw exception [org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.cac.hibernate.Sections.questions_set, no session or session was closed] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.cac.hibernate.Sections.questions_set, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.toString(PersistentSet.java:309)
at java.lang.String.valueOf(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at org.apache.tomcat.util.log.SystemLogHandler.println(SystemLogHandler.java:269)
at com.cac.dao.HibernateSectionsDAO.getAllSections(HibernateSectionsDAO.java:93)
at com.cac.service.SectionsServiceImpl.getAllSections(SectionsServiceImpl.java:48)
at com.cac.struts.RegisterAction.fetch_sections(RegisterAction.java:107)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:269)
at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:170)
at org.springframework.web.struts.DelegatingActionProxy.execute(DelegatingActionProxy.java:113)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:425)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:244)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:379)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:259)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:281)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
持久性类(Section)和传输对象(SectionsTO)就像这个部分
private int section_id;
private String section_name;
private String section_desc;
private int threads;
private int posts;
private String last_post;
private Members last_post_by;
private Date last_post_date;
private int question_id;
private Set<Questions> questions_set;
//setter
//getter
节TO
private int section_id;
private String section_name;
private String section_desc;
private int threads;
private int posts;
private String last_post;
private MembersTO last_post_by;
private Date last_post_date;
private int question_id;
private Set<QuestionsTO> questionsto_set;
//setter
//getter
问题是,如果我对集合执行lazy="true",我将得到一个延迟初始化异常,而如果我执行lazy="false",由于propertyutil 类实现,它会急切地加载所有表。从过去的 48 小时开始,我一直坚持这一点。所以请建议我一些优化的方法。