关于Hibernate session.flush()

的问题 我想询问以下情况下flush方法的实际用途:
for (int i = 0; i < myList.size(); i++) {
    Car c = new Car( car.get(i).getId(),car.get(i).getName() );
    getCurrentSession().save(c);
    if (i % 20 == 0)
        getCurrentSession().flush();
}
这是否意味着在迭代20之后,刷新缓存,然后20个持有的内存对象实际上保存在数据库中? 有人可以向我解释当条件成立时会发生什么。     
已邀请:
来自
Session#flush
的javadoc:   强制此会话刷新。一定是   在工作单元结束时调用,   在提交交易之前   结束会议(取决于   flush-mode,Transaction.commit()   调用这种方法)。      刷新是同步底层的过程   具有持久性的持久存储   国家在记忆中举行。 换句话说,
flush
告诉Hibernate执行将JDBC连接的状态与会话级缓存中保存的对象的状态同步所需的SQL语句。条件
if (i % 20 == 0)
将使每20的
i
倍数发生。 但是,仍然,新的
Car
实例将保存在会话级缓存中,对于大
myList.size()
,你将吃掉所有内存并最终得到一个
OutOfMemoryException
。为了避免这种情况,文档中描述的模式是定期(与JDBC批处理大小相同)对会话进行
flush
ANDѭ9,以持久保存更改,然后分离实例以便可以对它们进行垃圾回收:   13.1。批量插入      使新对象持久化时   flush()然后清除()会话   定期以控制大小   第一级缓存。
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}

tx.commit();
session.close();
该文档在同一章中提到了如何设置JDBC批处理大小。 也可以看看 10.10。刷新会话 第13章批处理     
取决于如何设置FlushMode。 在默认配置中,Hibernate尝试在三个位置与数据库同步。
1. before querying data
2. on commiting a transaction
3. explictly calling flush
如果将
FlushMode
设置为FlushMode.Manual,则程序员通知hibernate他/她将处理何时将数据传递给数据库。在此配置下
session.flush()
调用将对象实例保存到数据库。 实际上可以使用
session.clear()
调用来清除持久性上下文。     
// Assume List to be of 50 
for (int i = 0; i < 50 ; i++) {
        Car c = new Car( car.get(i).getId(),car.get(i).getName() );
        getCurrentSession().save(c);
    // 20 car Objects which are saved in memory syncronizes with DB 
        if (i % 20 == 0)
            getCurrentSession().flush();

}
关于为什么冲洗应该与批量大小相匹配的几点指针 要启用批处理,您需要设置jdbc批处理大小
// In your case 
hibernate.jdbc.batch_size =20
使用批处理的一个常见缺陷是,如果您使用单个对象更新或插入,这很好。但以防万一 您正在使用多个对象导致多个插入/更新,那么您将必须显式设置排序机制。 例如
// Assume List to be of 50 
    for (int i = 0; i < 50 ; i++) {
            Car c = new Car( car.get(i).getId(),car.get(i).getName() );
        // Adding accessory also in the card here
            Accessories a=new Accessories("I am new one");
            c.add(a);
        // Now you got two entities to be persisted . car and accessory 
        // Two SQL inserts 
            getCurrentSession().save(c);
        // 20 car Objects which are saved in memory syncronizes with DB 
        // Flush here clears the car objects from 1st level JVM cache
            if (i % 20 == 0)
            getCurrentSession().flush();
                    getCurrentSession().clear();
    }
在这种情况下     生成两个sql     1用于插入汽车     1用于插入附件 要进行正确的批处理,您必须设置
<prop  key="hibernate.order_inserts">true</prop>
所以汽车的所有插件都被整理在一起,并且所有附件的插件都被分类在一起。通过这样做你将有20个插件批量发射而不是一次一个sql发射。 对于一个事务下的不同操作,您可以查看http://docs.jboss.org/hibernate/core/3.2/api/org/hibernate/event/def/AbstractFlushingEventListener.html     
是每20个循环,为未保存的对象生成并执行sql。您还应将批处理模式设置为20以提高性能。     

要回复问题请先登录注册