java что - Вопрос о Hibernate session.flush ()





это руководство (5)


Зависит от того, как настроен FlushMode.

В конфигурации по умолчанию Hibernate пытается синхронизировать с базой данных в трех местах.

1. before querying data
2. on commiting a transaction
3. explictly calling flush

Если FlushMode установлен как FlushMode.Manual, программист информирует спящий режим, что он / она будет обрабатывать, когда передавать данные в базу данных. В этой конфигурации вызов session.flush() будет сохранять экземпляры объектов в базе данных.

Для очистки контекста стойкости можно использовать вызов session.clear() .

Я хочу узнать о том, что на самом деле делает метод 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 сохраненных объектов памяти фактически сохраняются в базе данных?

Может кто-нибудь, пожалуйста, объясните мне, что произойдет, когда условие будет истинным.




// 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 вставных стрелок в пакетной, а затем 1 кв. стрельбе за один раз.

Для разных операций в рамках одной транзакции вы можете посмотреть http://docs.jboss.org/hibernate/core/3.2/api/org/hibernate/event/def/AbstractFlushingEventListener.html




Из javadoc Session#flush :

Заставьте эту сессию сбросить. Должен быть вызван в конце единицы работы, прежде чем совершить транзакцию и закрыть сеанс (в зависимости от flush-mode Transaction.commit() вызывает этот метод).

Промывка - это процесс синхронизации основного сохраняющегося хранилища с сохраняемым состоянием в памяти.

Другими словами, flush сообщает Hibernate выполнять инструкции SQL, необходимые для синхронизации состояния соединения JDBC с состоянием объектов, хранящихся в кеше уровня сеанса. И условие if (i % 20 == 0) сделает это для каждого i кратного 20.

Но, тем не менее, новые экземпляры Car будут храниться в кеше уровня сеанса, и для большого myList.size() вы собираетесь съесть всю память и, в конечном итоге, получить OutOfMemoryException . Чтобы избежать этой ситуации, шаблон, описанный в документации, должен быть clear и clear сеанс с регулярными интервалами (такого же размера, как размер партии JDBC), чтобы сохранить изменения, а затем отсоединить экземпляры, чтобы они могли собираться в мусор:

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.

Смотрите также




Да каждые 20 циклов, sql генерируется и выполняется для несохраненных объектов. Также вы должны установить режим партии до 20 для увеличения производительности.




Поиск через Refresh: управляемые объекты могут быть перезагружены из базы данных с помощью метода обновления:

Содержимое управляемого объекта в памяти отбрасывается (включая изменения, если есть) и заменяется данными, которые извлекаются из базы данных. Это может быть полезно для обеспечения того, что приложение имеет дело с самой последней версией объекта сущности, на случай, если оно могло быть изменено другим EntityManager с момента его получения.

Источник: http://www.objectdb.com/java/jpa/persistence/retrieve







java hibernate orm