3

I'm trying to do that but not working, can anyone suggest me what i'm wrong? In the end I lose the first update

    EntityManager entityManager1 = JPAUtil.getEntityManagerFactory().createEntityManager();
    EntityManager entityManager2 = JPAUtil.getEntityManagerFactory().createEntityManager();

    Session session1 = (Session) entityManager1.getDelegate();
    Prova prova1 = session1.load(Prova.class, "020");

    Session session2 = (Session) entityManager2.getDelegate();
    Prova prova2 = session2.load(Prova.class, "020");

    prova2.setDes(prova2.getDes() + " 2");    
    prova1.setShortdes(prova1.getShortdes() + " 1");

    Transaction t2 = session2.beginTransaction();
    session2.update(prova2);
    t2.commit();
    session2.close();

    Transaction t1 = session1.beginTransaction();
    session1.update(prova1);
    t1.commit();
    session1.close();
EvilKenny
  • 33
  • 4

2 Answers2

1

Add the following code to fix:

    t2.commit();
    session2.close();
    session1.refresh(prova1)
    prova1.setShortdes(prova1.getShortdes() + " 1");

Transaction t1 = session1.beginTransaction();
    session1.update(prova1);
    t1.commit();

What is happening here is:

First you execute update on prova2 which results in des being updated.

Then on prova1 shortdes is updated , but its detached state of des is the original prova state before prova2 was updated. The algorithm of update is such that it attempts to reattach prova1 to the persistent context and realizes that it differes from the persistent state in two fields so the first update is ommited and you end up with shortDes set but Des is back to its original state.

Read more here https://www.baeldung.com/hibernate-save-persist-update-merge-saveorupdate

Alexander Petrov
  • 9,204
  • 31
  • 70
  • I want to ask you a question. Take this example: user1 open session and get Prova from DB with id '020'. User2 open another session and get Prova with id '020'. Now user1 modify des field and before he commits, user2 modify shortDes field. User1 commit and user2 commit. With this example I lose the first update. How can I not lose it? – EvilKenny Feb 17 '19 at 13:26
1

As the previous answer you always need to check the version of object before saving. Hibernate or JPA has features called optimistic locking to fix this issue. Refer to the below code and link for more information.

@Entity
public class Employee 
{
  @Id
  @GeneratedValue
  private Integer id;
  @Version
  private long version;
  private String name;
}

When you create employee record the framework will automatically create version value. At first lets assume the values are

[1, 0, "name1"]

On update it changes to

[1, 1, "name2"]

On next update it changes to

[1, 2, "name3"]

The framework will throw exception if you try to update data with wrong version

Link has more information on this https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/optimistic-lock.html