0

I have some transactional code:

import org.hibernate.Session;
void PersistRemovePersist(){ 
try {

    UserTransaction ut = getUt();
    EntityManagerFactory emf = getEmf();
    A = new some.Entity("A");

    ut.begin();
    EntityManager em = emf.createEntityManager();
    Session ss = em.unwrap(Session.class);
    saveOrUpdate(A);
    ut.commit();
    em.close();

    ut.begin(); //TX1
    EntityManager em = emf.createEntityManager();
    Person a = em.find(Person.class,db.A.getId());
    em.remove(a);
    ut.commit();
    em.close();

    ut.begin(); //TX2
    em = emf.createEntityManager();
    em.unwrap(Session.class).saveOrUpdate(A);
    ut.commit(); // <- wrapped StaleObjectStateException
    em.close();
    }catch (Exception e){
        throw new RuntimeException(e);
    }
}

At the code execution I get an exception:

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [some.Entity#1]

But why? TX1 and TX2 are serial, not parallel. What am I missing?

1 Answers1

0

saveOrUpdate() inserts if there is the generated ID is null, and updates if the generated ID is not null.

In your case, in TX2, it's not null (since it was generated in TX0). So it tries to update. But you deleted the entity in TX1. Hence the exception:

Row was updated or deleted by another transaction

Which is exactly what you did: you deleted the row in another transaction.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • And how is supposed to sole the "PersistRemovePersist" case? 1) because of above I can't merge() 2) I can't persist() because hibernate thinks that the Entity is detached 3) resetting Id(+associated objs) seems me very ugly – Артем Максимов Sep 08 '19 at 20:45
  • Why would you reinsert an entity that you deleted, and keep the same ID? Either you want to keep it, and you shouldn't delete it, or you want to delete it, and if you insert a new one later, it should have a newly generated ID, and properties that might be different, too. I fail to understand why you would want to do that. – JB Nizet Sep 08 '19 at 20:49
  • It is ugly way to refill DB after unit tests. But now I just want to do it because I think it must be possible. – Артем Максимов Sep 08 '19 at 20:57