Announcement Announcement Module
Collapse
No announcement yet.
fastest way to batch insert w/ hibernate Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Originally posted by mark_in_gr View Post
    Code:
    public class ImportXTFServiceImpl implements ImportXTFService{
        
    /** Creates a new instance of ImportXTFServiceImpl */
    public ImportXTFServiceImpl() {
    
    private static int saveCount = 0;
    private SessionFactory sessionFactory = null;
    private Session session = null;
    private Transaction transaction = null;
       
    public void setSessionFactory(SessionFactory sessionFactory) {
       this.sessionFactory = sessionFactory;
    }
    
    public void importBatch(Collection objs) {       
           
           session = this.sessionFactory.openSession();
           session.setCacheMode(CacheMode.IGNORE);
           session.getTransaction().begin();
                  
           for(Object o : objs) {           
               session.save(o);
               if(++saveCount % objs.size() == 0)
                {                       
                   session.getTransaction().commit();
                   session.clear();
                   saveCount = 0;
                }
           }       
           
           session.close();
        }
    The code above is most certainly not threadsafe. SessionFactory can safely be used as an instance variable, but not the Session. The scope "prototype" means a new instance is created, but per injection, not per request.

    Comment


    • #17
      Originally posted by dejanp View Post
      The code above is most certainly not threadsafe. SessionFactory can safely be used as an instance variable, but not the Session. The scope "prototype" means a new instance is created, but per injection, not per request.
      It wasn't my intention to make it not thread safe, in fact, I wanted to somehow mimic the behaviour derived from the use of getCurrentSession() when CurrentSessionContext was based on the ThreadLocalSessionContext implementation. But the way Spring overrides getCurrentSession() based on it's org.springframework.orm.hibernate3.LocalSessionFac toryBean implementation, the normal Hibernate getCurrentSession() behaviour is not observed.

      Comment


      • #18
        Originally posted by dejanp View Post
        The scope "prototype" means a new instance is created, but per injection, not per request.
        I don't believe that is entirely accurate based on the Spring Docs, which states that allong with being injected into another bean, any getBean() calls on the container will result in a new instance.

        Comment


        • #19
          Originally posted by mark_in_gr View Post
          I don't believe that is entirely accurate based on the Spring Docs, which states that allong with being injected into another bean, any getBean() calls on the container will result in a new instance.
          Yes, but invoker will not execute getBean() per request.

          Comment


          • #20
            Originally posted by mark_in_gr View Post
            It wasn't my intention to make it not thread safe, in fact, I wanted to somehow mimic the behaviour derived from the use of getCurrentSession() when CurrentSessionContext was based on the ThreadLocalSessionContext implementation. But the way Spring overrides getCurrentSession() based on it's org.springframework.orm.hibernate3.LocalSessionFac toryBean implementation, the normal Hibernate getCurrentSession() behaviour is not observed.
            To mimic ThreadLocalSessionContext you need to use ThreadLocal and not simple instance variable.

            Comment


            • #21
              Don't use session.isDirty() method! It returns true just with one insert:

              Code:
              if ( actionQueue.areInsertionsOrDeletionsQueued() ) {
                  log.debug("session dirty (scheduled updates and insertions)");
                  return true;
              }
              You must count the objects and flush and clear every batch size:
              Code:
              Session session = sessionFactory.openSession();
              Transaction tx = session.beginTransaction();
              
              for(int i=0; i<100000; i++){
              Customer customer =newCustomer(.....); session.save(customer); if( i %20==0){//20, same as the JDBC batch size
              [INDENT=2]//flush a batch of inserts and release memory: session.flush(); session.clear();[/INDENT]
              }
              } tx.commit(); session.close();

              http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#batch-inserts

              Comment

              Working...
              X