The correct place in the documentation for this type of treatment is Chapter 13. Batch processing .
There are some obvious errors in your current approach:
- You should not start / commit a transaction for each update.
you should enable the JDBC package and set it to a reasonable number (10-50):
hibernate.jdbc.batch_size 20
you must flush() and then clear() session at regular intervals (each n entries, where n is equal to the hibernate.jdbc.batch_size parameter), or it will continue to grow and may explode (with OutOfMemoryException ) at some point.
The following is an example in section 13.2. Batch updates illustrating this:
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); ScrollableResults customers = session.getNamedQuery("GetCustomers") .setCacheMode(CacheMode.IGNORE) .scroll(ScrollMode.FORWARD_ONLY); int count=0; while ( customers.next() ) { Customer customer = (Customer) customers.get(0); customer.updateStuff(...); if ( ++count % 20 == 0 ) {
You may also consider using StatelessSession .
Another option is to use DML-style operations (in HQL!): UPDATE FROM? EntityName (WHERE where_conditions)? UPDATE FROM? EntityName (WHERE where_conditions)? . This is an HQL UPDATE example:
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName"; // or String hqlUpdate = "update Customer set name = :newName where name = :oldName"; int updatedEntities = s.createQuery( hqlUpdate ) .setString( "newName", newName ) .setString( "oldName", oldName ) .executeUpdate(); tx.commit(); session.close();
Again, refer to the documentation for details (especially about how to handle version or timestamp property values ββusing the VERSIONED keyword).
Pascal thivent
source share