3

保存后何时应在休眠状态下提交事务。是在我调用 session.evict(obj) 之前还是之后。目前我的代码看起来像这样(只有必需的部分)。

Session session = connector.getSession();
Transaction tx = session.beginTransaction();
try {
        Criteria crit = session.createCriteria(ST_CODE_SETTINGS_STORE.class).add(Restrictions.eq("TYPE", "issueno"));
        List<ST_CODE_SETTINGS_STORE> ls = crit.list();
        if (ls.size() < 1) {
            session.save(st_code_settings_store);
            session.evict(st_code_settings_store);
            msg = "insert";
        } 
        else {
            Long Id = null;
            ST_CODE_SETTINGS_STORE st_code_settings_store1 = ls.get(0);
            Id = st_code_settings_store1.getCODE_ID();

            Object o = session.get(ST_CODE_SETTINGS_STORE.class, Id);
            ST_CODE_SETTINGS_STORE update = (ST_CODE_SETTINGS_STORE) o;
            session.update(update);
        }
        tx.commit();
    } catch (Exception e) {
        if (tx != null) {
            tx.rollback();
        }
        System.out.println("Error: " + e.getMessage());
        connector.printStack(e);
        throw e;
    } finally {
        session.close();
    }

有时,如果我在驱逐后提交,数据不会保存在数据库中。这是正确的编码方式吗?

4

1 回答 1

2

evict() 方法从会话缓存中删除单个对象。因此,在您调用 evict() 之前,该对象应该在 Session 缓存中。因此,如果您第一次保存对象,则必须通过 Session.save(object) 保存对象。后续更新调用应遵循 session.saveOrUpdate(object) 或 session.update(object) 在调用 evict() 以从缓存中删除加载的对象。(参考

休眠文档

结束会话通常涉及四个不同的阶段:

  • 刷新会话
  • 提交事务
  • 关闭会话
  • 处理异常

不要使用反模式 session-per-user-session 或 session-per-application (但是,此规则很少有例外)。以下一些问题也可能出现在推荐的模式中,因此请确保您在做出设计决策之前了解其中的含义:

  • 会话不是线程安全的。如果共享 Session 实例,并发工作的事物,如 HTTP 请求、会话 bean 或 Swing 工作程序,将导致竞争条件。如果您将 Hibernate Session 保留在 HttpSession 中(这将在本章后面讨论),您应该考虑同步对 Http 会话的访问。否则,单击重新加载速度足够快的用户可以在两个并发运行的线程中使用相同的会话。

  • Hibernate 抛出的异常意味着您必须立即回滚数据库事务并关闭会话(本章稍后将对此进行更详细的讨论)。如果您的 Session 绑定到应用程序,则必须停止应用程序。回滚数据库事务不会使您的业务对象回到事务开始时的状态。这意味着数据库状态和业务对象将不同步。通常这不是问题,因为异常是不可恢复的,无论如何您都必须在回滚后重新开始。

  • Session 缓存处于持久状态的每个对象(由 Hibernate 监视和检查脏状态)。如果长时间保持打开状态或只是加载过多数据,它会无限增长,直到出现 OutOfMemoryException。一种解决方案是调用 clear() 和 evict() 来管理 Session 缓存,但如果您需要大量数据操作,则应该考虑使用存储过程。

于 2016-02-19T05:18:07.690 回答