Hibernate:在不同的会话中更新相同的对象

Hibernate: update same object in different session

我正在尝试这样做但没有成功,任何人都可以告诉我我错在哪里吗? 最后我失去了第一个更新

    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();

添加以下代码修复:

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

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

这里发生的事情是:

首先,您在 prova2 上执行更新,这导致 des 被更新。

然后在prova1shortdes上更新,但是它的des detached状态是prova2更新前的原始prova状态。更新算法是这样的,它尝试将 prova1 重新附加到持久上下文,并意识到它在两个字段中与持久状态不同,因此第一次更新被忽略,你最终设置了 shortDes,但 Des 回到了它的原始状态。

在此处阅读更多内容https://www.baeldung.com/hibernate-save-persist-update-merge-saveorupdate

正如之前的回答,您总是需要在保存前检查对象的版本。 Hibernate 或 JPA 具有称为 乐观锁定 的功能来解决此问题。请参阅下面的代码和 link 了解更多信息。

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

当您创建员工记录时,框架会自动创建版本值。首先让我们假设值是

[1, 0, "name1"]

更新后变为

[1, 1, "name2"]

在下次更新时它变为

[1, 2, "name3"]

如果您尝试使用错误的版本更新数据,框架将抛出​​异常

Link 有更多关于此的信息 https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/optimistic-lock.html