21.4. 级联与未保存值(Cascades and unsaved-value)
假设我们从Session
中装入了一个Parent
对象,用户界面对其进行了修改,然后希望在一个新的Session里面调用update()
来保存这些修改。对象Parent
包含了子对象的集合,由于打开了级联更新,Hibernate需要知道哪些Child对象是新实例化的,哪些代表数据库中已经存在的记录。我们假设Parent
和Child
对象的标识属性都是自动生成的,类型为java.lang.Long
。Hibernate会使用标识属性的值,和version 或 timestamp 属性,来判断哪些子对象是新的。(参见第 10.7 节 “自动状态检测”.) 在 Hibernate3 中,显式指定unsaved-value
不再是必须的了。
下面的代码会更新parent
和child
对象,并且插入newChild
对象。
//parent and child were both loaded in a previous session
parent.addChild(child);
Child newChild = new Child();
parent.addChild(newChild);
session.update(parent);
session.flush();
Well, that's all very well for the case of a generated identifier, but what about assigned identifiers and composite identifiers? This is more difficult, since Hibernate can't use the identifier property to distinguish between a newly instantiated object (with an identifier assigned by the user) and an object loaded in a previous session. In this case, Hibernate will either use the timestamp or version property, or will actually query the second-level cache or, worst case, the database, to see if the row exists.
这对于自动生成标识的情况是非常好的,但是自分配的标识和复合标识怎么办呢?这是有点麻烦,因为Hibernate没有办法区分新实例化的对象(标识被用户指定了)和前一个Session装入的对象。在这种情况下,Hibernate会使用timestamp或version属性,或者查询第二级缓存,或者最坏的情况,查询数据库,来确认是否此行存在。