Flush Mode hibernate实用程序

时间:2014-12-05 10:37:26

标签: java hibernate

我试着了解不同的hibernate FlushMode之间的区别。为此,我创建了一个小插入示例。

    session.beginTransaction();
    session.setFlushMode(FlushMode.AUTO);// I tried ALWAYS AND MANUAL
    for (int i = 1; i < 4; i++) {
        Stock stock = new Stock();
        stock.setStockId(i);
        stock.setStockCode("code-"+i);
        stock.setStockName("name-"+i);

        session.save(stock);
        System.out.println("entity saved");
    }

    session.getTransaction().commit();

问题我总是有同样的行为,就像flushMode设置为COMMIT一样。

entity saved
entity saved
entity saved
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)

虽然我期待

entity saved
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
entity saved
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
entity saved
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)

任何人都有解释为什么我总是有相同的结果?

4 个答案:

答案 0 :(得分:1)

FlushMode.COMMIT的文档: 调用Transaction#commit时会刷新Session。

如果在循环内部提交事务,结果应该是您期望的结果。

问候 slowy

答案 1 :(得分:0)

for session.setFlush(FlushMode.COMMIT);

The Session is flushed when Transaction.commit() is called.
you can get your expected result by committing transaction inside for loop.
But every time you need to begin new transaction because existing will be closed when Transaction.commit() will be called.

答案 2 :(得分:0)

FlushMode.AUTO表示如果您发出查询,其中必须刷新插入或更新的实体,以便数据库提供正确答案,则会刷新会话。从文档

  

自动:在查询执行之前,有时会刷新会话   确保查询永远不会返回陈旧状态

在实际需要之前,Hibernate不会立即刷新新实体。 (除非您使用的是无状态会话)。如果由于某种原因需要这样做,则需要手动对会话执行刷新。

答案 3 :(得分:0)

经过多次测试后,我发现会话在每次查询之前都没有发生,因为Hibernate会话的目的是最大限度地减少对数据库的写入次数,因此如果认为这样做会避免刷新到数据库即使显式调用session.flush()也不需要它。这在org.hibernate.Session docs

中得到了证实
  

除非显式flush(),否则绝对不能保证Session何时执行JDBC调用,只保证它们执行的顺序。但是,Hibernate确保Query.list(..)永远不会返回过时或不正确的数据。

最后要看看刷新模式之间的区别,不要对单个实体起作用,因为hibernate认为刷新它没用。所以我在循环中添加了一个Query来强制Hibernate刷新。 虽然使用的模式总是

,但下面的代码不会刷新
session.beginTransaction();
session.setFlushMode(FlushMode.ALWAYS );
for (int i = 1; i < 4; i++) {
    Stock stock = new Stock();
    stock.setStockId(i);
    stock.setStockCode("code-"+i);
    stock.setStockName("name-"+i);
    session.save(stock);
    System.out.println("entity saved");
}
session.getTransaction().commit();

输出:

entity saved
entity saved
entity saved
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)

现在,如果我在System.out.println("entity saved");

之后添加
Query query = session.createQuery("from StockDailyRecord");
query.list();

输出将是:

entity saved
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
select stockdaily0_.STOCK_REC_ID as STOCK_RE1_1_ from stock_daily_record stockdaily0_
entity saved
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
select stockdaily0_.STOCK_REC_ID as STOCK_RE1_1_ from stock_daily_record stockdaily0_
entity saved
insert into stock (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
select stockdaily0_.STOCK_REC_ID as STOCK_RE1_1_ from stock_daily_record stockdaily0_