🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 21.4\. 级联与`未保存值`(Cascades and `unsaved-value`) 假设我们从`Session`中装入了一个`Parent`对象,用户界面对其进行了修改,然后希望在一个新的Session里面调用`update()`来保存这些修改。对象`Parent`包含了子对象的集合,由于打开了级联更新,Hibernate需要知道哪些Child对象是新实例化的,哪些代表数据库中已经存在的记录。我们假设`Parent`和`Child`对象的标识属性都是自动生成的,类型为`java.lang.Long`。Hibernate会使用标识属性的值,和version 或 timestamp 属性,来判断哪些子对象是新的。(参见[第 10.7 节 “自动状态检测”](../Text/pr01_split_000.html "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属性,或者查询第二级缓存,或者最坏的情况,查询数据库,来确认是否此行存在。