2012-12-20 26 views
2

我连接弹簧服务(有问题的),下面的代码:Spring + Hibernate的保存()不工作

@Async 
    public void performSeismicOperations(Integer sessionUserId, 
      int seismicFileId, String seismicFileName, ShClstr targetCluster, 
      Collection<String> listOperations, String processedFolderName, 
      Map<String, Object[]> args, String userNotes) throws IOException { 

      . 
      . 
      . 
      /*some code*/ 
      . 
      . 
     Date currentDate = new Date(System.currentTimeMillis()); 

      /*IMMEDIATE JOB ENTRY*/  
     log.info("Start : Inserting in sh_job to assure user"); 
     ShJob shJob = new ShJob(user, ClusterConstants.JOB_SUBMITTED, 
       currentDate, null, null, null); 
     shJobDAO.save(shJob); 
     log.info("End : Inserting in sh_job to assure user"); 

     /*some time-consuming operation - 1*/ 

     SeismicFiles processedSeismicFile = new SeismicFiles(user, 
       processedFolderName, 0, HDFSConstants.PROCESSED, currentDate); 
     seismicFilesDAO.persist(processedSeismicFile); 

     /*some time-consuming operation - 2*/ 

     log.info("Start : Updating the Hadoop job id"); 
     shJob.setShjHadoopJobId(hadoopJobId); 
     shJobDAO.attachDirty(shJob); 
     log.info("End : Updating the Hadoop job id"); 

      . 
      . 
      . 
      /*some code*/ 
      . 
      . 

     log.info("Returning from SeismicHadoopServiceImpl.performSeismicOperations()"); 
    } 

DAO代码

import java.util.List; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.hibernate.LockMode; 
import org.hibernate.Query; 
import org.hibernate.SessionFactory; 
import org.hibernate.criterion.Example; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Repository; 

import com.lnt.seismichadoop.pojo.ShJob; 

@Repository 
public class ShJobDAO { 

    private static final Log log = LogFactory.getLog(ShJobDAO.class); 

    @Autowired 
    private SessionFactory sessionFactory; 

    public void setSessionFactory(SessionFactory sessionFactory) { 
     this.sessionFactory = sessionFactory; 
    } 

    public void persist(ShJob transientInstance) { 
     log.debug("persisting ShJob instance"); 
     try { 
      sessionFactory.getCurrentSession().persist(transientInstance); 
      log.debug("persist successful"); 
     } catch (RuntimeException re) { 
      log.error("persist failed", re); 
      throw re; 
     } 
    } 

    public void save(ShJob transientInstance) { 
     log.debug("SAVING ShJob instance"); 
     try { 
      sessionFactory.getCurrentSession().save(transientInstance); 
      log.debug("save successful"); 
     } catch (RuntimeException re) { 
      log.error("save failed", re); 
      throw re; 
     } 
    } 

    public void attachDirty(ShJob instance) { 
     log.debug("attaching dirty ShJob instance"); 
     try { 
      sessionFactory.getCurrentSession().saveOrUpdate(instance); 
      log.debug("attach successful"); 
     } catch (RuntimeException re) { 
      log.error("attach failed", re); 
      throw re; 
     } 
    } 

    public void attachClean(ShJob instance) { 
     log.debug("attaching clean ShJob instance"); 
     try { 
      sessionFactory.getCurrentSession().lock(instance, LockMode.NONE); 
      log.debug("attach successful"); 
     } catch (RuntimeException re) { 
      log.error("attach failed", re); 
      throw re; 
     } 
    } 

    public void delete(ShJob persistentInstance) { 
     log.debug("deleting ShJob instance"); 
     try { 
      sessionFactory.getCurrentSession().delete(persistentInstance); 
      log.debug("delete successful"); 
     } catch (RuntimeException re) { 
      log.error("delete failed", re); 
      throw re; 
     } 
    } 

    public ShJob merge(ShJob detachedInstance) { 
     log.debug("merging ShJob instance"); 
     try { 
      ShJob result = (ShJob) sessionFactory.getCurrentSession().merge(
        detachedInstance); 
      log.debug("merge successful"); 
      return result; 
     } catch (RuntimeException re) { 
      log.error("merge failed", re); 
      throw re; 
     } 
    } 

    public ShJob findById(java.lang.Integer id) { 
     log.debug("getting ShJob instance with id: " + id); 
     try { 
      ShJob instance = (ShJob) sessionFactory.getCurrentSession().get(
        "com.lnt.seismic.dao.ShJob", id); 
      if (instance == null) { 
       log.debug("get successful, no instance found"); 
      } else { 
       log.debug("get successful, instance found"); 
      } 
      return instance; 
     } catch (RuntimeException re) { 
      log.error("get failed", re); 
      throw re; 
     } 
    } 

    public List findByExample(ShJob instance) { 
     log.debug("finding ShJob instance by example"); 
     try { 
      List results = sessionFactory.getCurrentSession() 
        .createCriteria("com.lnt.seismic.dao.ShJob") 
        .add(Example.create(instance)).list(); 
      log.debug("find by example successful, result size: " 
        + results.size()); 
      return results; 
     } catch (RuntimeException re) { 
      log.error("find by example failed", re); 
      throw re; 
     } 
    } 

    public List<ShJob> findAll() { 
     log.debug("finding JobStatus instance by findAll"); 
     try { 
      Query query = sessionFactory.getCurrentSession().createQuery(
        "from ShJob"); 
      List<ShJob> results = query.list(); 
      log.debug("find by findAll successful, result size: " 
        + results.size()); 
      return results; 
     } catch (RuntimeException re) { 
      log.error("find by example failed", re); 
      throw re; 
     } 
    } 
} 

我的要求是,一个项目必须去成作业表,一旦处理开始(/IMMEDIATE JOB ENTRY/中的代码)。/一些耗时的操作完成后 - 2 /,我将更新同一条目(用适当的状态)。 虽然我读保存(之差),坚持(),我保存()仍然推迟插入,直到/ 一些费时的操作 - 2 /这反过来,反映了一个条目前端很晚。

请指引我到哪里,我做一个大错。

1日编辑

在我的情况下,用户提交其涉及到标@Async上述服务方法的操作请求 - 用户必须看到一个页面,他的要求显示“提交”,而运营方式仍在继续。在这种情况下,我应该使用session.flush()还是需要进行任何代码更改?

+0

您是否尝试在保存后刷新更改 –

回答

3

savepersist,并且一般情况下,对持久实体进行的每项操作都将推迟到真正必要时,以避免不必要的往返数据库。

您可以让Hibernate使用session.flush()将每个挂起的更改写入数据库,但这不会使该实体可用于前端,因为ront-end不使用相同的事务来读取数据而不是长期运作并坚持实体的人。

而且由于事务处于隔离状态(大多数情况下默认隔离是READ_COMMITTED),事务在其他事务提交到数据库之前不会看到其他事务写入的任何内容。

如果你想瑟插入的实体,立即将其保存在单独的事务从长期运行操作的其余部分,或更改隔离级别READ_UNCOMMITTED。

+0

在我的情况中,用户提交了一个操作请求,该请求涉及上述服务方法,标记为@Async - 用户必须看到一个页面,其请求显示'已提交'而服务方法中的操作仍在进行。 在这种情况下,我将使用调用Session.flush()或者我需要更改代码? –

+0

正如我说:你需要有一个单独的事务刚刚保存工作,并继续长时间操作之前提交。 Session.flush()将无济于事。 –

+0

u能提供的示例代码,我怎么也得做(单独交易)? –

相关问题