Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rollback a series of persist statements in JPA?

Tags:

java

jpa

I have a situation where i a need to rollback a series of persist method. I have a method in my controller class, from where I am calling the persist method.

Controller class:

@EJB
private jpa.session.ClassMasterFacade ejbFacadeCM;
@EJB
private jpa.session.StudentMasterFacade ejbFacadeSM;
@EJB
private jpa.session.ParentsMasterFacade ejbFacadePM;
@EJB
private jpa.session.AddressMasterFacade ejbFacadeAM;

public String confirmData() {
    try {
        ejbFacadeSM;.create(selectedSM);
        ejbFacadeCM;.create(selectedCM)
        ejbFacadeAM;.create(selectedAM);
        ejbFacadePM;.create(selectedPM);
    } catch (Exception e) {
        //rollback all
        JsfUtil.addErrorMessage(e, ResourceBundle.getBundle ("/resources/Bundle").getString("PersistenceErrorOccured"));
        return null;
    }
 }

Example Facade class:

@Stateless
public class ClassMasterFacade extends AbstractFacade<ClassMaster> {

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

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public ClassMasterFacade() {
        super(ClassMaster.class);
    }

}

All other facade classes are similar to the above class. The abstract class is:

public abstract class AbstractFacade<T> {
    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }
}

I want to rollback all the create method if any exception is found.

I searched and found some answers:

  • Roll back transaction after exception in JPA + Spring
  • How to prevent JPA from rolling back transaction?

I am new to JPA and just started exploring it. Am I missing some concept?

there is till a problem, dont know if it is related. In all the entity class, i have a autogenerated key as updated. the problem is that if the exception occurs in second create statement, the autogenerated key for the first create statement is generated but still not updated in mysql as excepted..But in case of success all statement, the key sequence is broken.

Entity Class:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "class_group_id")
private Integer classGroupId;
like image 288
rahul Avatar asked Dec 19 '15 05:12

rahul


People also ask

How do I rollback JPA transactions?

Transaction Rollback. The @Transactional annotation is the metadata that specifies the semantics of the transactions on a method. We have two ways to rollback a transaction: declarative and programmatic. In the declarative approach, we annotate the methods with the @Transactional annotation.

What is the difference between persist and merge in JPA?

persist(Object entity): Make an instance managed and persistent. merge(T entity): Merge the state of the given entity into the current persistence context.

How do I persist a list in JPA?

Since JPA 2.0, you can use an element collection to persist a Collection of value types. You just need to annotate the attribute with @ElementCollection and the persistence provider will persist the elements of the Collection in an additional database table.

Can we use persist for update?

You can use the methods persist and save to store a new entity and the methods merge and update to store the changes of a detached entity in the database.


1 Answers

Use a javax.transaction.UserTransaction, which is available to you in any standard Java EE environment.

Usage is fairly straightforward, inject it and use the following methods:

  • begin() to start a transaction
  • commit() if all operations were successful and you want to commit the results
  • rollback() if an error occurred and you want to roll back to the point in time when begin() was called

See: Oracle documentation on UserTransaction

@Resource
UserTransaction tran;

...

public void confirmData (){

    tran.begin();
    try {
        ejbFacadeSM.create(selectedSM);
        ejbFacadeCM.create(selectedCM)
        ejbFacadeAM.create(selectedAM);
        ejbFacadePM.create(selectedPM);

        // Create's succeeded, commit transaction.
        tran.commit();
    } catch (Exception e) {
        // Error occurred, rollback transaction
        tran.rollback();
    }
}
like image 176
Andy Guibert Avatar answered Oct 12 '22 14:10

Andy Guibert