Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rollback transaction in JPA?

I have an EntityManager object maintained by the Spring framework and I inject it in whatever DAO class I want using the @PersistenceContext annotation like this..

@PersistenceContext(unitName="entityManager")
private EntityManager em;

I use those DAO classes to save in the database something like this..

class MyClass
{
    @Resource(name="myDao")
    private MyDao dao;

    @Resource(name="myAnotherDao")
    private MyAnotherDao anotherDao;

    public void save(String s1,String s2)
    {
        try
        {
             MyEntity m=new MyEntity();
             m.setName(s1);
             // .. and so on ..

             XYZ x=new XYZ();
             x.setDEF(s2);

             anotherDao.save(x);

             m.setXYZ(x);
             // .. some other stuff .. //
             dao.saveEntity(m);
         }
         catch(Exception e)
         {
             // I would like to rollback the transaction
         }
     }
}

Now, both the daos here use the same EntityManager injected through @PersistenceContext(unitName="entityManager"). Now, if an exception occurs after setXYZ(), then I would like to rollback even the saved XYZ entity. But, how do I get the EntityManager from that?

If all the daos hold the same object, then can I just call the getTransaction().rollback() method of the EntityManager class? Does the getTransaction() return a new transaction or any transaction that is currently associated with EntityManager?

like image 950
JavaTechnical Avatar asked Oct 05 '14 06:10

JavaTechnical


2 Answers

  1. If you used Spring AOP to manage transaction, and the configuration and annotation is used right, the default effect is the transaction would be rolled back when the runtime exception occurs.

  2. If you managed transaction manually, you can roll back transaction like this:

    EntityManager em = createEntityManager();
    
    try {
    
        em.getTransaction().begin();
        // Do something with the EntityManager such as persist(), merge() or remove()
        em.getTransaction().commit();
    } catch(Exception e) {
    
        em.getTransaction().rollback();
    }
    
    em.close();
    

See more at: http://en.wikibooks.org/wiki/Java_Persistence/Transactions http://www.developerscrappad.com/547/java/java-ee/ejb3-x-jpa-when-to-use-rollback-and-setrollbackonly/#sthash.jx3XlK5m.dpuf

like image 55
huangyp Avatar answered Oct 27 '22 11:10

huangyp


It will be rollback once you throw any RuntimeException from a method marked as @Transactional like below:

By default, all RuntimeExceptions rollback transaction where as checked exceptions don't:

@Transactional(rollbackFor={MyRuntimeException.class, AnotherRuntimeException.class})
public SomeVal someTransactionalMethod(){
   ...
}
like image 34
PKumar Avatar answered Oct 27 '22 12:10

PKumar