Java 获得;org.hibernate.StaleObjectStateException;在单个事务中更新表的同一行时
我有一个名为Employee的表,它有一个复杂的主键,即它的3个列的组合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
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)