Announcement Announcement Module
Collapse
No announcement yet.
HibernateCursorItemReader and statefulsession Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • HibernateCursorItemReader and statefulsession

    hi,

    from javadoc of HibernateCursorItemReader<T> :

    "When stateful session is used it will be cleared after successful commit without being flushed (no inserts or updates are expected)."

    the commit above mean the commit-interval's commit (chunk comit)? or hibernate database transaction commit ? if is the chunk commit, mean the session only store small amount of object in memory and will clear on commit-interval right? so we no need to worry the session in overload until throws exception.


    Due to the stateful session in reader can't obtain by ItemProcessor and Writer, I wondering in future will spring batch eventually support a common template in hibernate world like code below, which is possible to do in chunk oriented:

    Code:
    // this code for item reader, like current implementation.
    Session session = sessionFactory.getCurrentSession();
    		String SELECT = "from User";
    
    		session.setCacheMode(CacheMode.IGNORE);
    		session.setFlushMode(FlushMode.MANUAL);
    		
    		ScrollableResults cursor = session.createQuery(SELECT).scroll(ScrollMode.FORWARD_ONLY);
    
    //the code here in Item processor
       //doing whatever on User object, e.g delete. insert, update.
    
    //the code here is in writer.
      //log the object.. etc
    
    //this code maybe in infrastructure 
                 if ( ++count % 50 == 0 ) {
    		session.flush();
                    session.clear();
    	     }	
    
    	     cursor.close();
    all the code above will be bound to same database transaction (hence we can process the object without worry about the session.)

    this scenario is quite useful (at least to me ) which involve the stateful session, like:

    1) iterate the user, get the notification criterion and notify user.
    2) delete inactive user

    and etc which can take advantages of batch processing (retry, restart etc).

    any idea ?

    happy hacking
    --------------
    kiwi
    Last edited by kiwi; May 13th, 2009, 04:04 AM.

  • #2
    I saw your earlier post, but I still don't understand what you mean. You can always write yourself a Tasklet if you really desperately need a reader and processor to share a Hibernate Session. But since I don't understand the use case, or what went wrong when you tried it, I'm not sure what to suggest.

    Comment


    • #3
      hi, sorry for confusing.

      1) from the spring batch javadoc class HibernateCursorItemReader<T> : "....When stateful session is used it will be cleared after successful commit without being flushed (no inserts or updates are expected)."

      is the successful commit mean the spring batch commit or hibernate transcation commit ? if is batch commit, mean the stateful session will clean the session after commit-interval, right ?


      2) I hava an scenario which use chunk oriented process to delete user, I use HibernateCursorItemReader as my reader, but the thing is I can't operate my user object due to the session in reader no expose to itemProcessor (exception is throw), is that any way to solve this ?

      3) is that any future plan for spring batch to support a common pattern in hibernate world like open a transaction, get a cursor, then iterate on object and consistent flush and clear the session, then close the cursor and commit when code. (code slow below)

      i find this pattern is widely use, i think this maybe can integrate to spring batch (so we can retry, restart etc )

      Code:
      //get an session and start transaction
      
      //code in Item reader
      ScrollableResults users = session.createQuery(SELECT).scroll(ScrollMode.FORWARD_ONLY);
      
      //this code in ItemProcessor
      //process on object.. 
      session.delete(user);  //this is not working now
      
      //this code in Item writer
      //do sth here
      
      //clear and flush session
      if ( ++count % 50 == 0 ) {
      	session.flush();
      	session.clear();
      }		
      
      //commit the transaction and close the session.

      please not hesistate to ask if u got any question not clear (that is my fault, if got any)

      happy hacking
      --------------
      kiwi
      Last edited by kiwi; May 14th, 2009, 04:52 AM.

      Comment


      • #4
        1) I updated the Javadocs to make it a bit clearer. It should say that the flush occurs on update() (which in turn will be called normally by the Step just before commit). Since the Session in the reader has to span multiple transactions, it has to be non-transactional itself.

        2) You can always session.lock(user,LockMode.NONE) in your ItemProcessor. Doesn't something like that work? I suppose you might have to grab the reader's session to evict the usr from there first. Not sure unless I try it.

        3) I don't really understand the proposal. Maybe we could provide a Hibernate reader that uses the current session. Is that what you mean?

        Comment


        • #5
          hi, some more question

          1) if i turn on stateful session and i i loop thought say 1000 object in itemprocessor, the session will be flush and clear at the commit time, right ? (if i set commit-interval to 10, mean only 10 object maximum in hibernate session, right? )

          2) is that any way to get the reader's session ?

          3) basically i had a HibernateCursorItemReader<User> which turn on stateful session, my ItemProcessor<User, User> which contain code like session.delete(user), but since the user object is in reader's hibernate session, I can't simple open a hibernate session and call session.delete(user), this will causing hibernate exception.

          I wondering is that anyway do to it ?
          Last edited by kiwi; May 14th, 2009, 10:16 AM.

          Comment


          • #6
            1) if i turn on stateful session and i i loop thought say 1000 object in itemprocessor, the session will be flush and clear at the commit time, right ? (if i set commit-interval to 10, mean only 10 object maximum in hibernate session, right? )
            10 User objects, yes.
            3) ...I can't simple open a hibernate session and call session.delete(user), this will causing hibernate exception.
            That's why I recommended Session.lock(). Maybe you need to read up on the Hibernate user guide and find the features you need there.

            Comment

            Working...
            X