Home » Java » java – After Transaction is finished, we are returning object as null-Exceptionshub

java – After Transaction is finished, we are returning object as null-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I am working on the code which is calling, transaction after transaction.

@Asynchronous
@TransactionTimeout(value = 12, unit = TimeUnit.HOURS)
public void runExport(Long id) {
    /*
    *   some stuff that takes time
    */

    em.persist(objectTest);
    manager.runAnotherTransaction(id);
}

@Asynchronous
@TransactionTimeout(value = 1, unit = TimeUnit.HOURS)
public void runCopy(Long id) {
    if(manager.isPreviousValueCommited(id)){
        //do some stuff
    }
    /*
    *   some stuff that takes time
    */

}


//other class
public void runAnotherTransaction(long id){
    //...
    superBean.runCopy(id);
}

public void isPreviousValueCommited(long id){
    //Thread.sleep(1000) if we sleep here, object wont be null
    SomeObject obj = em.find(SomeObject.class, id); //is null, 
}

As you can see in code, first transaction method is persisting object, and after that we are calling other method via some kind of manager, and second transaction want to check some stuff on the previously commited object. But as you probably suspect it cant, because object does not exist in database (first transaction was not able to save it before we ask db). When I give some sleep before finding this object everything is ok.

This sample code is pretty simple, and it is probably make sense to not pass id, but object itself(true?) to avoid this problem, but I have question. But I would like to listen another ideas or pros/cons(possibly there is much more cons) of this approach of connecting Transaction as I have in example.

How to&Answers:

Using em.persist() you definitly do not commit any data. And most of the times you do even not write any data to database.

Your data is committed automatically by the container after the call of an EJB-Method. So after runExport the data will commit. Before that the container will also flush the data to database.

You can do that programmatically as well using em.flush(). But again, this will not commit your data, just write it.

If your really want to control the transaction by yourself, you have to use @TransactionManagement(TransactionManagementType.BEAN). The Interface javax.transaction.UserTransaction defines the methods you need.