/**
* 学期课程
*/
@Entity
@Table(name="T_kc_TermCourse")
public class TermCourse extends AbstractPersistentInfo {
// 学期
private Term term;
// 课程
private Course course;
@ManyToOne
@JoinColumn(name="term")
public Term getTerm() {
return term;
}
//...此处省略无关的属性及setter\getter方法
}
我在更新 TermCourse 实体中的 term 属性时发生了这样的异常。但更新对象的外键属性是非常常见的操作,为什么在这一次不行呢。后来查看代码,才发现了问题所在。
/**
* @param termCourse 是前端页面传输过来的数据
*/
public String edit() throws Exception {
TermCourse temp = termCourseService.getById(termCourse.getId());
temp.getTerm().setId(termCourse.getTerm().getId());
termCourseService.update(temp);
}
原来代码中在更新termCourse实体时先通过hibernate的关联查询,将term对象查询出来,然后再修改term的id主键。最后将修改后的termCourse持久化到数据库中。
这样做是错误的,因为通过关联查询 term 属性 处于持久态(Hibernate中bean对象被划分为三个状态:瞬时态、持久态、托管态),该状态下的term对象已经交给hibernate管理了,此时修改了它的id主键,被hibernate检测到,才会引发该异常。若将瞬时态的term设为该termCourse对象的属性,即可解决该异常