Hibernate:行被另一个事务更新或删除(或未保存值映射不正确)
Posted
技术标签:
【中文标题】Hibernate:行被另一个事务更新或删除(或未保存值映射不正确)【英文标题】:Hibernate: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) 【发布时间】:2013-05-17 19:45:34 【问题描述】:首先抱歉。我知道它有很多相同的主题,但也许我的英语不好或者我没有找到正确的答案。
我使用乐观锁定@Version 注解。我需要一个表中的一对一的行有来自不同表的许多行,我确实像这样插入:
所以它必须看起来像这样:
机构(这是我的表(机构)的行之一)
- CreationDate A (this is row from different table(CreationDate) bind with Institution with JoinTable, ManyToMany) - CreationDate B (this is row from different table(CreationDate) bind with Institution with JoinTable, ManyToMany) - CreationDate C (this is row from different table(CreationDate) bind with Institution with JoinTable, ManyToMany)
因此,为了将这个 CreationDate 放入不同的变体中,我决定为我想要添加我的 CreationDate 的特定机构手动输入 ID。
我的主要方法类:
CreationDate crdate = new CreationDate();
Institution inst= new Institution();
Set<Institution> instituset = new HashSet<Institution>();
***inst.setInstitutionId(2);***
inst.setNameOfInstitution("MyInstitution");
inst.setTypeName("Education");
instituset.add(inst);
当我想将另一行数据附加到我的机构时,我在代码中添加了带有星号的行在第一次将我的版本行插入数据库后更改为一个。
这里是我的机构实体:
@Entity
@Table(name="INSTITUTION")
public class Institution implements Serializable
private static final long serialVersionUID = -7636394097858726922L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="INSTITUTION_ID")
private int institutionId;
@Version
@Column(name="VERSION")
private int version;
@Column(name="NAME_INSTITUTION")
private String nameOfInstitution;
@Column(name="TYPE_NAME")
private String typeName;
@ManyToMany(mappedBy="institution", fetch = FetchType.LAZY)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
private Set<CreationDate> creationDate = new HashSet<CreationDate>();
//getter and setter methods ommited
public String toString()
return institutionId + " , " + nameOfInstitution + " , " + typeName
还有我的 CreatioDate 实体:
@Entity
@Table(name="CREATION_DATE")
public class CreationDate implements Serializable
private static final long serialVersionUID = 1648102358397071136L;
@Id
@GeneratedValue(strategy=IDENTITY)
@Column(name="DATE_ID")
private int dateId;
@Column(name="PARTICULAR_DATE")
private Date particularDate;
@Version
@Column(name="VERSION")
private int version;
@Temporal(TemporalType.DATE)
@Column(name="CHILD_GO_SCHOOL_DATE")
private Date childGoSchoolDate;
@Temporal(TemporalType.DATE)
@Column(name="CHILD_ADMISSION_DATE")
private Date childAdmissionDate;
@ManyToMany(fetch = FetchType.LAZY)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
@JoinTable(name="CREATIONDATE_INSTITUTION",
joinColumns=@JoinColumn(name="DATE_ID"),
inverseJoinColumns=@JoinColumn(name="INSTITUTION_ID"))
private Set<Institution> institution = new HashSet<Institution>();
@OneToMany(fetch=FetchType.EAGER, orphanRemoval=true)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
@JoinTable(name="SRC_DATE", joinColumns=@JoinColumn(name="DATE_ID"),
inverseJoinColumns=@JoinColumn(name="SRC_ID"))
private List<ScheduleRotationChild> scheduleRotationChild = new ArrayList<ScheduleRotationChild>();
//getter and setter methods ommited
public String toString()
return dateId + " , "
+ particularDate + " , "
+ childGoSchoolDate + " , "
+ childAdmissionDate + " " + scheduleRotationChild ;
我的道:
public CreationDate insertData(CreationDate creationdate)
sessionFactory.getCurrentSession().saveOrUpdate(creationdate);
log.info(creationdate.getDateId());
return creationdate;
所以当我第二次尝试将我的数据插入我的机构时发生异常。
Hibernate: insert into CREATION_DATE (CHILD_ADMISSION_DATE,
CHILD_GO_SCHOOL_DATE, PARTICULAR_DATE, VERSION) values (?, ?, ?, ?)
Hibernate: insert into SCHEDULE_ROTATION_CHILD (CHILD_ADMITTED,
CHILD_GO_SCHOOL, CHILD_UNDER_3_YEARSOLD, CHILD_UPPER_3_YEARSOLD,
DAY_SCHEDULE, NUMBER_OF_CHILD, ROTATION, VERSION, WORK_SCHEDULE)
values (?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update INSTITUTION set
NAME_INSTITUTION=?, TYPE_NAME=?, VERSION=? where INSTITUTION_ID=? and
VERSION=? Exception in thread "main"
org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException:
Object of class [edu.demidov.dom.Institution] with identifier [2]:
optimistic locking failed; nested exception is
org.hibernate.StaleObjectStateException: Row was updated or deleted by
another transaction (or unsaved-value mapping was incorrect):
[edu.demidov.dom.Institution#2]
【问题讨论】:
【参考方案1】:我遇到了同样的问题,它是 spring 和 hibernate 的组合。折腾了 3-4 个小时后,我只是随机检查了我的与版本相关的专栏。因为我使用的是一个旧表,我最近在其中引入了版本列,并且没有默认为零 - 所以它为所有行添加了 null
以及我试图删除的行。所以就像我猜测的那样,我输入了 0,并且神奇地它在下一次运行中起作用。我希望这会有所帮助。
【讨论】:
我也损失了大约 3 个小时,这对我来说是个问题,一个版本列是空的。谢谢! 我在删除列名为“errors”的实体时遇到了类似的问题,它带有序列化的 json 字符串。当列为空时,删除工作正常。但是当它携带非空值时,它会抛出上述异常。仍在试图找出根本原因。任何帮助将不胜感激。【参考方案2】:如果我理解正确,您正在尝试将 ID 为 2 的现有机构添加到新的 CreationDate。由于机构已经存在,您不应创建新机构。您应该简单地从 Hibernate Session 中获取它:
Institution institution = (Institution) session.load(Institution.class, 2);
creationDate.addInstitution(institution);
【讨论】:
您好先生.. 很高兴再次见到您,您是我的编程恩典。谢谢你的宝贵答案。先生,我正在尝试将 CreationDate 添加到数据库中机构 ID 为 2 的现有机构。第一次插入采取行动没有问题,但第二次有错误。但还要考虑我的 DAO 代码,我没有声明任何事务,但它无论如何都做事务???。非常感谢您的帮助。 是的,这就是我的回答向您展示的方法。事务应该在服务层开始,而不是在 DAO 层。 哦,我不知道事务应该在服务层启动,我是这项技术的新手。很多事情不知道。对于这个不恰当的问题,我很抱歉。但也许你指出我正确的方向是如何使用两个参数提取数据来提取数据,因为我也无法弄清楚这一点。就像我想在一个查询中提取与特定名称和特定日期相对应的数据。在这里和对你的行为不是那么糟糕吗?谢谢。 最好的参考是一本好书,或者官方文档:docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single【参考方案3】:检查您将要更新的模型对象。 基本上你应该检查你的“非空”值; 像已经定义的和主键等。这会有所帮助。
【讨论】:
我忘记将 'id' 作为隐藏值传递给我的表单,所以它被设置为默认值 0,这在 db 中不存在,因此尝试抛出此异常休眠更新。【参考方案4】:对我来说,问题是我总是使用相关JpaRepository
的save
方法,而没有先获取现有实体。因此,第一次保存总是很顺利,但是当我更新实体时抛出了异常。我检查了数据库中的version
列,发现版本永远不会超过 1。确保在更新之前始终尝试获取实体!
【讨论】:
以上是关于Hibernate:行被另一个事务更新或删除(或未保存值映射不正确)的主要内容,如果未能解决你的问题,请参考以下文章