I am using Spring/Hibernate done the JPA way using org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
and configured using spring xml, persistence.xml and JPA 2 annotations.
Functionally it is fine and persisting correctly. However, I have a requirement to store entity A which has a bidirectional OneToMany with a large collection of B as quickly as possible.
I am using various options in persistence.xml to try to speed up inserts and reduce memory use (the application writes about as much as it reads)
<property name="hibernate.id.new_generator_mappings" value="true" />
<property name="hibernate.jdbc.batch_size" value="50" />
<property name="hibernate.order_inserts" value="true" />
<property name="hibernate.order_updates" value="true" />
<property name="hibernate.cache.use_query_cache" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="false" />
and the persist is done using
entityManager.persist(instanceOfA)
Edit Additional info:
Each entity has a generated id like this:
@Id
@Column(name="ID")
@GeneratedValue(strategy=GenerationType.AUTO, generator="SEQUENCE_GENERATOR")
@SequenceGenerator(name="SEQUENCE_GENERATOR", sequenceName="MY_SEQUENCE", allocationSize=50)
private Long id;
which relates to an Oracle sequence
CREATE SEQUENCE MY_SEQUENCE MINVALUE 1 MAXVALUE 999999999999999999999999999 START WITH 1 INCREMENT BY 50 NOCYCLE NOCACHE NOORDER;
When I run the code with show sql on I can see lots of insert statements taking quite a while.
I have read that I need to call entityManager.flush(); entityManager.clear();
every 50 rows inserted.
Does this mean that I need to break up the persist into
entityManager.persist(instanceOfA);
instanceOfA.addB(instanceOfB);
entityManager.persist(instanceofB);
adding a flush clear every 50 calls to persist()
?
Is there a cleaner way of doing it? (my actual object hierarchy has about 7 layers of relations like A and B)
I was thinking about using JDBC for the inserts, but I hate writing row mappers :)
I have heard about org.hibernate.StatelessSession
but there is no method of getting that from a JPA entity manager without casting to SessionFactory at some point - again not very clean.
Thanks in advance!