随笔-42  评论-578  文章-1  trackbacks-0

    本文是我用EJB+JPA(Hibernate实现)+Web Service开发时,遇到的一些问题,查了许多地方,都找不到答案,请各位朋友耐心读一下本文,有想法的欢迎留言!谢谢! 

    Category.java的部分代码:

  1. @OneToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY,mappedBy="category")   
  2. public List<News> getNewsList() {   
  3.     return newsList;   
  4. }   
  5. public void setNewsList(List<News> newsList) {   
  6.     this.newsList = newsList;   
  7. }  

 

    News.java的部分代码:

  1. @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.EAGER)   
  2. @JoinColumn(name="cid")   
  3. public Category getCategory() {   
  4.     return category;   
  5. }   
  6. public void setCategory(Category category) {   
  7.     this.category = category;   
  8. }  

 

   NewsDaoBean.java的部分代码:

  1. @PersistenceContext(unitName="newspstn")   
  2. private EntityManager em;   
  3.   
  4. /**  
  5.  * 添加新闻  
  6.  * @param cid 项目编号  
  7.  * @param news  
  8.  */  
  9. public void saveNews(int cid,News news) {   
  10.     news.setCategory(em.find(Category.class, cid));   
  11.     em.persist(news);   
  12. }   
  13.   
  14. /**  
  15.  * 查询所有新闻列表  
  16.  * @return  
  17.  */  
  18. @SuppressWarnings("unchecked")   
  19. public List<News> listNews() {   
  20.     return (List<News>)em.createQuery("from News n").getResultList();   
  21. }  

 

    业务逻辑层的类(NewsManager.java)比较简单,由于篇幅问题,这里就不贴出来了。

   

    在还没有发布成Web Service前,用Juint测试:

  1.  //测试保存新闻   
  2. public void testSaveNews() {   
  3.     InitialContext ctx;   
  4.     try {   
  5.         ctx = new InitialContext();   
  6.         NewsManager manager = (NewsManager)ctx.lookup("NewsManagerBean/remote");   
  7.         News news = new News();   
  8.         news.setTitle("title2");   
  9.         news.setAuthor("author2");   
  10.         news.setContent("content1");   
  11.         manager.saveNews(1, news);   
  12.     } catch (NamingException e) {   
  13.         System.out.println("NamingException");   
  14.         e.printStackTrace();   
  15.     }   
  16. }   
  17.   
  18. //测试查询新闻列表   
  19. public void testListNews() {   
  20.     InitialContext ctx;   
  21.     try {   
  22.         ctx = new InitialContext();   
  23.         NewsManager manager = (NewsManager)ctx.lookup("NewsManagerBean/remote");   
  24.         List<News> newsList = manager.listNews();   
  25.         for(News news : newsList){   
  26.             System.out.println("news.title = " + news.getTitle());   
  27.         }   
  28.     } catch (NamingException e) {   
  29.         System.out.println("NamingException");   
  30.         e.printStackTrace();   
  31.     }   
  32. }  

   这个测试是没有问题的,(testSaveNews和testListNews)能正常添加和查询。

 

    当发布成Web Service后,在客户端生成相应的服务代理类,再在Web服务的客户端用Junit测试:

  1. //测试保存新闻   
  2. @Test  
  3. public void testSaveNews(){   
  4.     NewsManagerService service = new NewsManagerService();   
  5.     NewsManager manager = service.getNewsManagerPort();   
  6.     News news = new News();   
  7.     news.setTitle("title1");   
  8.     news.setAuthor("author1");   
  9.     news.setContent("content1");   
  10.     manager.saveNews(1, news);   
  11. }   
  12.   
  13. //测试查询新闻列表   
  14. @Test  
  15. public void testListNews(){   
  16.     NewsManagerService service = new NewsManagerService();   
  17.     NewsManager manager = service.getNewsManagerPort();   
  18.     List<News> newsList = manager.listNews();     //------a1   
  19.     for(News news : newsList) {                             //--------a2   
  20.         System.out.println("news.title = " + news.getTitle());   //----a3   
  21.     }                         //------a4   
  22. }  

    这次测试,保存新闻的的操作(testSaveNews)能正常,但查询新闻列表(testListNews)的操作却抛以下异常

  1. 12:19:37,781 INFO  [STDOUT] Hibernate:    
  2.     select   
  3.         news0_.id as id1_,   
  4.         news0_.content as content1_,   
  5.         news0_.cid as cid1_,   
  6.         news0_.title as title1_,   
  7.         news0_.author as author1_,   
  8.         news0_.pubtime as pubtime1_    
  9.     from   
  10.         rong_news news0_   
  11. 12:19:37,781 INFO  [STDOUT] Hibernate:    
  12.     select   
  13.         category0_.id as id0_0_,   
  14.         category0_.cname as cname0_0_    
  15.     from   
  16.         rong_category category0_    
  17.     where   
  18.         category0_.id=?   
  19.   
  20. 12:19:37,796 ERROR [LazyInitializationException] failed to lazily initialize a collection of role: rong.entity.Category.newsList, no session or session was closed   
  21. org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: rong.entity.Category.newsList, no session or session was closed   
  22. (……相关的异常堆栈信息略……)   
  23.   
  24. 12:19:37,796 ERROR [RequestHandlerImpl] Error processing web service request   
  25. org.jboss.ws.WSException: javax.xml.ws.WebServiceException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: rong.entity.Category.newsList, no session or session was closed   
  26. (……相关的异常堆栈信息略……)   
  27.   
  28. Caused by: javax.xml.ws.WebServiceException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: rong.entity.Category.newsList, no session or session was closed   
  29. (……相关的异常堆栈信息略……)   
  30.   
  31. Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: rong.entity.Category.newsList, no session or session was closed   
  32. (……相关的异常堆栈信息略……)   
  33.   
  34. 12:19:37,890 ERROR [[NewsManagerBean]] Servlet.service() for servlet NewsManagerBean threw exception   
  35. org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: rong.entity.Category.newsList, no session or session was closed   
  36. (……相关的异常堆栈信息略……)  

 

补充说明1:如果我把上面testListNews方法中的a1,a2,a3,a4行注释掉,Junit测试是正常的。

补充说明2:在Category类中,对List<News> newsList的设置,我确定是设置了延迟加载(Lazy)的,而且,我在查询 新闻列表时,没有用到news.getCategory.getNewsList()之类的操作。有个疑问:是不是设置的lazy加载,即使没有用到,也会加载的?即使会加载的,为什么我在服务器端测试时能正常,而在Web Service的客户端测试时,却报错?

 

是EJB Web Service的Bug还是我的程序有错误?请大家讨论!



本文原创,转载请注明出处,谢谢!http://www.blogjava.net/rongxh7(心梦帆影JavaEE技术博客)
    

posted on 2009-04-26 13:27 心梦帆影 阅读(1561) 评论(4)  编辑  收藏 所属分类: EJB3WebService

评论:
# re: 是它的Bug还是我的错误:EJB的WebService客户端报LazyInitializationException异常[未登录] 2009-06-23 20:50 | freefly
貌似和我的问题一模一样ejb发布成webservice之前可以测试调用
发布之后,生成代理类后可以插入,不能查询出!不知 lz搞定这个问题没·  回复  更多评论
  
# re: 是它的Bug还是我的错误:EJB的WebService客户端报LazyInitializationException异常 2010-09-09 16:35 | wothnet
是延遲載加方面的問題。強制延遲加載的對象進行初始化!或者取消延遲加載  回复  更多评论
  
# re: 是它的Bug还是我的错误:EJB的WebService客户端报LazyInitializationException异常 2011-08-09 16:35 | 鹅鹅鹅
怎么处理?  回复  更多评论
  
# re: 是它的Bug还是我的错误:EJB的WebService客户端报LazyInitializationException异常 2011-08-12 13:18 | xiaomaha
这个问题我也遇到了,超级郁闷,无论是否延迟加载,只要用到ws都会出现session 问题,楼主是否解决此问题,请把解决方案贴出来啊,,,我现在只有通过@XmlTransient 加到实体中可以解决这样的问题!用了这个方法只能让webservice忽略它而已。但实际问题依然未被解决,还有一个问题,就是延迟加载关闭后,就会出现循环引用的bug,也只能通过@XmlTransient 得到解决,哎,,,,,,,,,,,  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: