Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: How does the Hibernate implementation of Savepoint work?
PostPosted: Tue Dec 21, 2010 9:26 am 
Beginner
Beginner

Joined: Tue Dec 21, 2010 5:26 am
Posts: 25
Hi all,

I'm using Hibernate on a very simple table. CRUD Operations all work well. How can I use Savepoints during a Transaction?
I tried doing it the doWork way. But that only seems to ignore my set savepoint.

Some code:
Code:
Transaction tx = HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();

User user1 = userDAO.findById(new Integer(1), false);
user1.setFirstname("Jane");
userDAO.saveOrUpdate(user1);

SetSavepointWork work = new SetSavepointWork("my_savepoint");
HibernateUtil.getSessionFactory().getCurrentSession().doWork(work);
Savepoint savepoint = work.getSavepoint();

user1.setFirstname("John");
userDAO.saveOrUpdate(user1);
HibernateUtil.getSessionFactory().getCurrentSession().doWork(new Work(){
         public void execute(Connection connection) throws SQLException
         {
            connection.rollback(savepoint);
         }
      });
tx.commit();


The SetSavepointWork is a simple implementation of the Work interface. In addition it holds set Savepoint object and has the getter for it.

What am I doing wrong? I'm expecting the firstname to be 'Jane' after the commit. But it's like Hibernate completely ignores the savepoint and the resulting firstname in the database is: John.

I really hope you guys can help. I don't know where else to look as there's very information about Hibernate and Savepoints out there...

Thanks,
Michael


Top
 Profile  
 
 Post subject: Re: How does the Hibernate implementation of Savepoint work?
PostPosted: Wed Dec 22, 2010 6:31 am 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2296
Location: Third rock from the Sun
what are you trying to do?
I don't see a "first commit" in your example code, just one in the end. Remember: all operations you ask hibernate to do might be postponed until the transactionmanager commits, that greatly optimizes performance as we can figure out best plan to update the graph, or remove some work, avoid unneeded connections.

So you're creating the savepoint, rolling back to it, and then commit which means, change the name to John and then commit for real.
If you need the operation to be flushed before, use flush().

But you shouldn't need this, there are better patterns. You could for example avoid the savepoint at all just using Session.clear() to cancel all not yet perfomred operations.

_________________
Sanne
http://in.relation.to/


Top
 Profile  
 
 Post subject: Re: How does the Hibernate implementation of Savepoint work?
PostPosted: Tue Jan 04, 2011 3:37 am 
Beginner
Beginner

Joined: Tue Dec 21, 2010 5:26 am
Posts: 25
Thanks for the reply - Sorry for the delay.

Well I'm trying to set a state in the transaction to which I can roll back to. And I was (am) under the impression that a session/transaction needs to be open for a rollback of such sort... Correct me if I'm wrong.

I was trying it in the same manner I would be doing it in sql: e.g.
BEGIN;
INSERT INTO table1 VALUES (1);
SAVEPOINT my_savepoint;
INSERT INTO table1 VALUES (2);
ROLLBACK TO SAVEPOINT my_savepoint;
INSERT INTO table1 VALUES (3);
COMMIT;

The above transaction will insert the values 1 and 3, but not 2

There the commit occurs at the end... not between operations.

Thanks


Top
 Profile  
 
 Post subject: Re: How does the Hibernate implementation of Savepoint work?
PostPosted: Tue Jan 04, 2011 9:46 am 
Beginner
Beginner

Joined: Tue Dec 21, 2010 5:26 am
Posts: 25
I think I got it now. This seems to work:

Code:
Transaction tx = HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();

User user1 = userDAO.findById(new Integer(1), false);
user1.setFirstname("Jane");
userDAO.flush();


Savepoint savepoint = userDAO.setSavepoint("my_savepoint");

user1.setFirstname("John");
userDAO.flush();

userDAO.rollbackSavepoint(savepoint);
tx.commit();


Resulting firstname in the database is "Jane". I guess I simply lacked knowledge of the flush mechanism.


The savepoint methods in the DAO looks as followed:
Code:
private Savepoint savepoint;

public Savepoint setSavepoint(final String savePoint)
{
   getSession().doWork(new Work()
   {
      public void execute(Connection connection) throws SQLException
      {
         savepoint = connection.setSavepoint(savePoint);
      }
   });
   return savepoint;
}

public void rollbackSavepoint(final Savepoint savepoint)
{
   getSession().doWork(new Work(){
      public void execute(Connection connection) throws SQLException
      {
         connection.rollback(savepoint);
      }
   });
}


Thanks for your support. I hope this is how it it meant to be used.

The Session.clear() thing isn't quite what I need. Too powerful you could say. Since some not yet performed operations might be wanted while others might not be. So sadly, clearing everything isn't an option...


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.