2012-07-05 86 views
0

我使用休眠3.5.1决赛,与春天3.0.5.RELEASE ,我使用下面的配置的OpenSessionInViewFilter延迟加载不@服务类工作

<filter> 
    <filter-name>hibernateFilter</filter-name> 
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> 
    <init-param> 
     <param-name>sessionFactoryBeanName</param-name> 
     <param-value>sessionFactory</param-value> 
    </init-param> 
    </filter> 
    <filter-mapping> 
    <filter-name>hibernateFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
    <dispatcher>FORWARD</dispatcher> 
    <dispatcher>REQUEST</dispatcher> 
    <dispatcher>ERROR</dispatcher> 
    </filter-mapping> 

假设我有以下实体

@SuppressWarnings("serial") 
@Entity 
@Table(name = "adpage", catalog = "mydb") 
public class Adpage implements java.io.Serializable { 

    @Id 
    @Column(name = "pkid", nullable = false, length = 50) 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(fetch = FetchType.EAGER) 
    private long pageId; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "audio_file_id", unique = true, nullable = true) 
    private AudioFile audioFile ; 

} 

和我支持bean如下:

@Component("myBean") 
@Scope("view") 
public class MyBean { 

    @Autowired 
    private AdPageDao adPageDao; 

    @Autowired 
    private AdPageService adPageService; 

    public void preRender() { 
       adPageObj = adPageDao.getAdPageByID(adPageId); 
    } 

    public void deleteAdPage(Adpage adPage) { 
     adPageService.deleteAdPage(adPage); 
    } 



} 

服务如下:

@Service 
public class AdPageService { 

    @Autowired 
    private AudioFileDao audioFileDao; 

    public void deleteAdPage(Adpage adPage) { 


     if (adPage.getAudioFile() != null) { 
      log.debug("deleting audio file: " 
        + adPage.getAudioFile().getName() + " for adpage: " // exception here 
        + adPage.getName()); 
      audioFileDao.deleteAudioFile(adPage.getAudiofileref()); 
      GeneralUtils.deleteFilePhysically(adPage.getAudioFile() 
        .getName(); 
     } 

    } 


} 

XHTML页面如下:

<f:event type="preRenderView" listener="#{myBean.preRender}" /> 
<ice:panelGrid columns="2"> 

       <ice:outputLabel id="fileName">File Name:</ice:outputLabel> 
       <ice:outputText value="#{myBean.adPageObj.audioFile.originalName}"></ice:outputText> 

       <ice:outputLabel id="fileLength">File Length:</ice:outputLabel> 
       <ice:outputText value="#{myBean.adPageObj.audioFile.length}"></ice:outputText> 

       <ice:outputLabel id="fileDesc">Description:</ice:outputLabel> 
       <ice:outputText value="#{myBean.adPageObj.audioFile.description}"></ice:outputText> 

       </ice:panelGrid> 

在懒惰加载的xhtml页面没有问题,文件数据是正常显示,但在删除文件时,我收到以下错误在删除服务方法:AdPageService.deleteAdPage

Could not initialize proxy - no Session 

请告知如何解决这个错误。

回答

2

如果AdPage对象已加载到您的视图中(由于OpenSessionInViewFilter而导致之前的Hibernate会话),则延迟加载不起作用,因为实体现在是“分离”的。

为了解决延迟加载问题,你可以这样做:

  1. reattach the entity当前的Hibernate会话
  2. 做一个预先抓取之前,确保所有属性都加载
  3. 重装实体通过它的id (pageId这里)

我会去选项3(通过它的ID重新加载)来获得一个新的实体(这可能已经改变,同时显示/提交表格)。

+0

,有没有办法检查实体是否分离?我想要做的是重新加载服务方法中的实体,如果它只是分离的,因为这个方法用于实体可能不被分离的其他地方。 – 2012-07-08 08:04:43

+1

@Msaleh:你可以查询Hibernate session directy:'session.contains(myEntity)'... – jeha 2012-07-08 10:40:29