延迟加载在@Service类中不起作用

时间:2012-07-05 11:30:56

标签: spring hibernate java-ee lazy-loading lazy-initialization

我正在使用 hibernate 3.5.1-Final spring 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

请告知如何解决此错误。

1 个答案:

答案 0 :(得分:2)

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

要解决延迟加载问题,您可以这样做:

  1. reattach the entity到当前的Hibernate会话
  2. 之前执行急切获取以确保加载所有属性
  3. 按其ID(pageId此处)
  4. 重新加载实体

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