Friday, December 27, 2013

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: 2259
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...

5 comments:

  1. asics gel lyte v blanche homme Vous allez lire achat nike flyknit lunar beaucoup de souffrances de cette douleur qui ont obtenu leur soulagement simplement de l'art de la marche. Néanmoins, l'enlèvement des chaussures nike air max cage printemps 2013 cicatrices chéloïdes n'est pas impossible! Mais vous devez d'abord trouver le bon remède. Et asics gel lyte 3 glow in the dark femme bien qu'il y ait vraiment beaucoup trop de fonctionnalités dans l'environnement du cigare à considérer nike air jordan 11 retro low gg pour ce post, j'ai supposé que je pourrais fournir un certain nombre de conseils pendant la asics gel noosa tri 10 navy stratégie pour le briquet allume-cigare, peut-être un accent important que vous pouvez avoir ( attaché avec l'humidor adidas zx flux homme soldes bien sûr).

    ReplyDelete