【发布时间】:2011-06-02 19:49:19
【问题描述】:
我正在使用 Spring 3、Hibernate 3.3.1 和 MySQL 5.1.x(在 red hat 5 上,但在 windows 上也看到相同的行为)。我注意到数据库中的一行正在更新,但内存中的一个对象引用没有被刷新。我将尝试以简化的形式描述类结构..
class A {
@OneToMany(cascade = CascadeType.ALL)
List<Widget> widgets;
@OneToMany(cascade = CascadeType.ALL)
@Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
List<B> bObjects;
@Transactional
public void turnOnWidgets() { ... }
}
class B {
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
@Cascade(value = { org.hibernate.annotations.CascadeType.LOCK, org.hibernate.annotations.CascadeType.EVICT})
private A aObj;
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void turnOnWidgets() {
for (Widget w : aObj.getWidgets()) {
w.setOn(true);
}
}
}
class Widget {
Boolean on;
}
这是操作的顺序。当 A.turnOnWidgets 被调用时,它会遍历其“bObjects”集合并在每个 B 对象上调用“turnOnWidgets”。 B 对象修改 A 对象引用的每个小部件的“on”属性(如上图 B.turnOnWidgets 所示)。
发生这种情况时,我可以查看数据库并看到小部件的“on”值已更改。但是,当我使用调试器进入代码时,我注意到 B 对象引用了 A 的不同实例(例如,数据库中的相同 A,但在内存中它是不同的 Java 对象实例),而不是我调用“turnOnWidgets”的 A开。
实际上我看到的是,当我通过查看 A 实例包含的小部件来导航对象图时,小部件“on”属性为假。但是,如果我通过从 B.aObj.getWidgets() 导航来查看小部件,它们的“on”属性为 true。
当我的应用程序在 Oracle 数据库上运行时,一切正常,一旦我切换到 MySQL,我开始看到这个问题。
有人知道MySQL 是否有什么特别之处(可能与 Hibernate 和/或 Spring 结合使用)?
更新 所以我想我已经把它缩小到代码中对“B”对象执行JPA“刷新”的部分。当针对 oracle 运行时,这会导致对象在内存中正确刷新,但是,当针对 MySQL 运行时,对象没有被正确更新。仍然需要弄清楚原因。
【问题讨论】:
标签: java mysql hibernate spring jpa