0
votes

I need to insert an object to database which has multiple nested objects like:

class A{
    List<B> b;
}

class B{
    List<C> c;
    List<D> d;
    List<E> e;
}

Now I will have a single object of A to persist which will have multiple objects of type B and B in turn will have multiple C, D and E type objects.

There could be a total of 10,000 objects of B, C, D and E combined. I have configured batch inserts using the below additions to my hibernate.cfg.xml

<property name="hibernate.jdbc.batch_size">50</property>
<property name="hibernate.order_inserts">true</property>
<property name="hibernate.order_updates">true</property>
<property name="hibernate.jdbc.batch_versioned_data">true</property>

I have also added

rewriteBatchedStatements=true

in the connection.url property of hibernate.

I am using an increment generator for the id's. I will receive a json of A along with nested list of B and inturn nested C, D and E in every B element. This is converted to an Object A and saved into db using

session.save(A);

Since, I've enabled cascading, all the nested objects are persisted into db. The total insertion time for 10,000 objects takes around 25 seconds. I'm not sure if the batching is enabled or not because I see single insert statements like

insert into C(id, val) values(1,"val");
insert into C(id, val) values(2,"val2");

I referred the hibernate batch insert doc, it asks me to

session.flush();
session.clear();

after jdbc batch size inserts. I'm not sure how do I do this in my case, I also tried using Stateless session, I didn't see any improvements there either. Any suggestions as to how can I improve the performance would be great.

1

1 Answers

0
votes

I think you might be able to improve the performance here if you change your approach slightly. So instead of a single cascaded save you could individually save the entities. This assumes you have bi-directional relationships declared which I think you'll need if you want this to perform.

So remove all the List<T> from A and then save A on its own.

Something like:

session.save(a)
session.evict(a)

This means A has been persisted but is not longer in the session. You can then individually save the associated entities:

for (B b : a.getListOfB()) {
  b.setA(a);
  session.save(b);
}

You can then flush and evict or use a stateless session if you'd prefer.