Java 获得;org.hibernate.StaleObjectStateException;在单个事务中更新表的同一行时

Java 获得;org.hibernate.StaleObjectStateException;在单个事务中更新表的同一行时,java,hibernate,Java,Hibernate,我有一个名为Employee的表,它有一个复杂的主键,即它的3个列的组合 firstName : String SecondName : String bossId : foreingKey of other table named Boss ( auto generated database sequence) 这是我的代码: @Entity @Table(name = "Employee") @org.hibernate.annotations.Entity(optimisticLock

我有一个名为Employee的表,它有一个复杂的主键,即它的3个列的组合

firstName : String
SecondName : String
bossId : foreingKey of other table named Boss ( auto generated database sequence)
这是我的代码:

@Entity
@Table(name = "Employee")
@org.hibernate.annotations.Entity(optimisticLock = OptimisticLockType.ALL, dynamicUpdate = true)
public class Employee {

private EmployeePk employeePk;  

private int age;
private String status;


@EmbeddedId
public EmployeePk getEmployeePk() {
    return employeePk;
}
public void setEmployeePk(EmployeePk employeePk) {
    this.employeePk = employeePk;
}


@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null ||
            !(o instanceof Employee)) {

        return false;
    }

    Employee other
    = (Employee)o;

    // if the id is missing, return false
    if (getEmployeePk() == null) return false;


    if( getEmployeePk().equals(other.getEmployeePk())) {            
        return true;
    } else {
        return false;
    }

}

@Override
public int hashCode() {
    if (getEmployeePk() != null) {
        return getEmployeePk().hashCode();
    } else {
        return super.hashCode();
    }
}
}

}

现在,一切都正常运行,我能够在Employee表中创建/更新/删除数据库行

但是,当我试图在一个事务中更新相同的行时,我会遇到以下异常:

org.hibernate.event.def.AbstractFlushingEventLis
tener: Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect):
    at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1792)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2435)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:64)
    at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:996)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1141)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    at org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:835)
我对另一个名为Contractor的表也有类似的问题,但能够通过重写其equals和hashCode方法来解决这个问题

问题是,在该表中只有一个名为“id”的主键,它是数据库自动生成的序列,因此存在 那里没有
EmbeddedId
的概念

我不确定我在这里哪里出了问题。我花了几天时间来解决这个问题,并遵循了几个链接,例如:

一些想法:

1) 使用optimisticLock=OptimisticLockType.ALL会让我产生怀疑。我自己从来没有用过这个,但我怀疑这可能与你的错误有关

2) 我认为equals方法不能处理任何属性为null的情况。它将始终返回false,即使两个实例相同


3) Hibernate确实更喜欢使用专用id(和版本,如果需要)列而不是自然键。根据我的经验,对复合/自然密钥的支持似乎既麻烦又有缺陷。

请发布正在进行更新的应用程序代码1)那么,使用optimisticLockType.ALL应该做些什么?我可以换成其他的吗?1)那么使用optimisticLockType.ALL应该怎么做?我换个别的好吗?2) 这等于你在这里所说的。首先执行空检查,然后执行等于检查。如果equals在任何情况下都返回false,那么它应该创建条目,但不是这样发生的。我认为equals和hashcode方法没有被重写。我不知道为什么3)有任何方法可以在类中拥有虚拟id。但在数据库中并没有这样的自动生成Id,主键是3列的组合1)您应该发布事务代码,这样我们就可以理解您试图做什么。2) 我说的是pk对象上的equals/hashcode。没有调用hashcode/equals并不奇怪。例如,见。3) 不,最好的解决方案是在数据库中添加一个id/version列。
org.hibernate.event.def.AbstractFlushingEventLis
tener: Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect):
    at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1792)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2435)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:64)
    at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:996)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1141)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    at org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:835)