Rajkishan Swami
Rajkishan Swami

Reputation: 3759

JPA Transaction not rolling back

I was trying to do a small sample update like below:

@RestController
@RequestMapping("/customer")
public class CustomerController {

@Autowired
private EntityManager eManager;

@RequestMapping(value = "/updatepincode/pincode/{pincode}", method = RequestMethod.GET)
//@Transactional
public String updateAddress(@PathVariable("pincode") String pinCode) {
    try {
        eManager.getTransaction().begin();
        Query query = eManager.createQuery("UPDATE Addresses SET pincode = :pincode WHERE addressid = :addressid");
        int updateCount = query.setParameter("pincode", pinCode).setParameter("addressid", "714D9F99-E19E-4595-9C5A-3560C42B1389").executeUpdate();
        eManager.getTransaction().commit();
        if (updateCount > 0) {
            System.out.println("Number of records updated = " + updateCount);
        }
    } catch (Exception ex) {
        eManager.getTransaction().rollback();
        LogService.error(this.getClass().getName(), ex);
        return "Failed to update";
    }
    return "Record Updated";
 }
}

I knowingly did this update to see what exceptions are thrown when I try to update another row with an existing primary key. As expected it threw javax.persistence.PersistenceException with cause com.microsoft.sqlserver.jdbc.SQLServerException. But after this error, I cannot open the table any more. I am sure, it is because the transaction is not rolled back. But as you can see I have eManager.getTransaction().rollback() in my catch block. I can open the table only after the service is stopped.

Why it is not rolling back?

Also tried with @Transactional annotation, but no use.

Note: I use SQLServer 2008. Other types of queries work fine. Update also works fine if there is no constraint violation.

Is this how we rollback in JPA or there is some other method?

I did this because in Hibernate, I did something like (catch block);

if(transaction.wasCommited(){
   transaction.rollback();
}

Upvotes: 0

Views: 1752

Answers (1)

user2173738
user2173738

Reputation:

I don't know where did you get this code but it not supposed to run correctly. Consider to rewrite it and probably use JTA for transaction management.

@Resource public UserTransaction utx;
@Resource public EntityManagerFactory factory;

public String updateAddress(@PathVariable("pincode") String pinCode) {
    EntityManager em = factory.createEntityManager();
    try {
        Query query = em.createQuery("UPDATE Addresses SET pincode = :pincode WHERE addressid = :addressid");
        int updateCount = query.setParameter("pincode", pinCode).setParameter("addressid", "714D9F99-E19E-4595-9C5A-3560C42B1389").executeUpdate();
        utx.commit();
        if (updateCount > 0) {
            System.out.println("Number of records updated = " + updateCount);
        }
    catch (RuntimeException e) {
        if (utx != null) utx.rollback();
        LogService.error(this.getClass().getName(), ex);
            return "Failed to update";
    }
    finally {
        em.close();
    }
     return "Record Updated";
 }

Upvotes: 1

Related Questions