I also need to create many objects very fast. these objects should be linked to other objects mapped to tables. if the linked entity does not exist, I'm creating a new entity, and then create my main object.
so, I'm trying to use "batch" mode to speed up the process. I'm using this code:
Code:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
..............
TestBean test = null;
try {
test = DBManager.getTest(session,
suiteBean.getId(), testName);
} catch (ObjectNotFoundException ex1) {
test = new TestBean(testName);
session.save(test);
suiteBean.getTests().add(test);
session.update(suiteBean);
}
... some code to create "testResultBean" object and linked entities....
session.save(testResultBean);
if (number % JDBC_BATCH_SIZE == 0) {
// flush a batch of inserts and release memory:
session.flush();
session.clear();
}
...........
session.getTransaction().commit();
and that's what I have on Hibernate 3.1:
Quote:
Found two representations of same collection: com....SuiteBean.tests
org.hibernate.HibernateException: Found two representations of same collection: com.....SuiteBean.tests
at org.hibernate.engine.Collections.processReachableCollection(Collections.java:153)
at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:37)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:124)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:195)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:35)
at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:954)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1526)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
at org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:305)
the problem dissapears if I remove
Code:
session.clear();
but then every next N rows insertion speed becomes slower and slower:
e.g. first 50 entities are created in 0.2 sec,
then next 50 entities - 0.4 sec,
then 0.7, etc. the time grows up
significantly!
I have to create about 2000 objects in one working cycle, so without clear() operation it works VERY (!) slow when the row index becomes more than, say, 500-800.
I'm using session.flush() to use JDBC batch mode effectively, as supposed in one of the tutorials. when ~50 objects are created in JVM, I'm using flush(), so they are written to DB. it works fine, and the problem is with session.clear() at this moment.
I have read about Session.setFlushMode(), but I don't want to change the default mode.
note:
without clear() method, everything works fine for me, but
slower and slower with each 100 results. and
with clear() I get this Exception.
I think I need to find the root problem of that exception.
I know that another option could be using a
stateless session, but the documentation says:
Quote:
Collections are ignored by a stateless session.
so, if I try to work with linked objects, I get another error:
Code:
suiteBean.getTests().add(test);
Code:
failed to lazily initialize a collection of role: com....beans.SuiteBean.tests, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com....beans.SuiteBean.tests, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.write(AbstractPersistentCollection.java:183)
at org.hibernate.collection.PersistentSet.add(PersistentSet.java:165)
at com....harvester.Harvester.loadXMLFile(Harvester.java:226)
at com....harvester.Harvester.loadFiles(Harvester.java:369)
at com....harvester.Harvester.<init>(Harvester.java:346)
at com....harvester.Harvester.main(Harvester.java:393)
does this mean that I can't use stateless session in my case and should revert back to stateful and fight with that "
Found two representations of same collection" error?