Spring + Hibernate save()不起作用

时间:2012-12-20 07:11:43

标签: spring hibernate

我正在附加下面的Spring服务(有问题)代码:

@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 /后,我将更新相同的条目(具有适当的状态)。 当我读到save()和persist()之间的区别时,我的save()仍然推迟插入直到/ 一些耗时的操作 - 2 /反过来反映了一个很晚的条目前端。

请指导我在哪里犯错误。

第一次编辑

在我的情况下,用户提交一个操作请求,该请求来自上面标记为@Async的服务方法 - 当操作仍在服务方法中时,用户必须看到一个页面,其请求显示为“SUBMITTED” 。在这种情况下,我应该使用session.flush()还是我需要进行任何代码更改?

1 个答案:

答案 0 :(得分:3)

savepersist,并且通常,您对持久性实体执行的每个操作都会被推迟到必要时,以避免不必要的往返数据库。

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

由于事务是隔离运行的(大多数情况下默认隔离是READ_COMMITTED),在另一个事务提交到数据库之前,事务不会看到由另一个事务写入的任何事务。

如果要立即关闭插入的实体,请将其保存在与长时间运行的其余操作不同的事务中,或将隔离级别更改为READ_UNCOMMITTED。