12

I'm using hibernate + play! framework at work, is there a "best practice" on inserting a good amount of records using hibernate? They are around 6,000 to 10,000 per text file so I don't know if Hibernate is going to choke on the job or throw an exception.

Any suggestion let me know, let me know if I have to explain more

Kartoch
  • 7,610
  • 9
  • 40
  • 68
allenskd
  • 1,795
  • 2
  • 21
  • 33

5 Answers5

24

From *Java Persistence and Hibernate" (Manning) and following a comment from Pangea, use a stateless session (which doesn't have a persistence context cache) :

StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
    Item item = new Item(...);
    session.insert(item);
}
tx.commit();
session.close();
Kartoch
  • 7,610
  • 9
  • 40
  • 68
  • 4
    I would not use Session for bulk operations. StatelessSesssion is meant to do bulk operations like this as it doesn't maintain 1st level cache: Change "sessionFactory.openSession()" to "sessionFactory.openStatelessSession()". Read section "13.3" from here http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html – Aravind Yarram Jan 03 '11 at 20:03
  • Thank you Pangea, I didn't know this one. – Kartoch Jan 03 '11 at 21:41
  • I'm not sure session.clear() need to be kept in this example: no need to evict all objects from the session cache because there is not cache with stateless session. I will wrote this in the source... – Kartoch Jan 04 '11 at 14:52
  • 5
    I should mention that the new `StatelessSession class` does not provide (save, flush, clear). It's pretty much straightforward, it would be `session.insert(item)` then commit and session.close() – allenskd Jan 11 '11 at 23:35
  • 2
    For me, `Session` should be `StatelessSession` while using sessionFactory.openStatelessSession(); – Arun Kumar Oct 30 '14 at 07:06
  • @allenskd Thanks, I fixed it. – Kartoch Mar 28 '16 at 12:00
3

Just some corrections of the codes in the answer of Kartoch.

According to Batch Procession, "The insert(), update() and delete() operations defined by the StatelessSession interface are considered to be direct database row-level operations. They result in the immediate execution of a SQL INSERT, UPDATE or DELETE respectively. They have different semantics to the save(), saveOrUpdate() and delete() operations defined by the Session interface."

No more save(), flush(), clear() for StatelessSession. The code should be like this :

StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
  Item item = new Item(.....);
  session.insert(item );
}    

tx.commit();
session.close();

Finally, Here is a discussion of the difference between the normal batch inserting and the StatelessSession insert : Using StatelessSession for Batch processing.

Community
  • 1
  • 1
Qianyue
  • 1,767
  • 19
  • 24
2

Best is to use StatelessSessions. Consider the following example from (http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/batch.html):

StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();

ScrollableResults customers = session.getNamedQuery("GetCustomers")
    .scroll(ScrollMode.FORWARD_ONLY);
while ( customers.next() ) {
    Customer customer = (Customer) customers.get(0);
    customer.updateStuff(...);
    session.update(customer);
}

tx.commit();
session.close();
HosseinSafy
  • 139
  • 1
  • 4
1

Just open your session and transaction.

Add all elements in the save of the session.

Then commit the transaction.

//Remember to effective handler errors
public void saveAll(List<Object> list) throws Exception{
Session s = HibernateUtil.openSession();
Transaction tx = s.beginTransaction();
for(Object obj : list)
 s.save(obj);
tx.commit();
s.flush();
s.close();
}
Marcos Vasconcelos
  • 18,136
  • 30
  • 106
  • 167
  • 3
    Please, don't do this. For batch transactions, it's better to avoid the session caching, otherwise, you'll face a OOM exception. For this specific scenario exists the StatelessSession, as mentioned by Pangea in Kartoch's answer. – jpkroehling Jan 04 '11 at 12:21
-5

You can always get a Connection object directly in case you want to do the inserts outside of hibernate.

Connection connection = DB.getConnection();
chad
  • 2,542
  • 1
  • 21
  • 6