04_传智播客hibernate教程_Session接口及getloadpersist方法 2

Hibernate users have requested a general purpose method that either saves a transient instance

by generating a new identifier or updates/reattaches the detached instances associated with its

current identifier. The saveOrUpdate() method implements this functionality.

// in the first session

Cat cat = (Cat) firstSession.load(Cat.class, catID);

// in a higher tier of the application

Cat mate = new Cat();

cat.setMate(mate);

// later, in a new session

secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id)

secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)

瞬时对象,游离对象通过saveOrUpdate方法转变成持久对象

  1 瞬时对象 执行save

  2 游离对象 执行Update

在你无法确定这个对象的状态时候,应用此方法

The usage and semantics of saveOrUpdate() seems to be confusing for new users. Firstly, so

long as you are not trying to use instances from one session in another new session, you should not need to use update(), saveOrUpdate(), or merge(). Some whole applications will never use either of these methods.

如果 需要一个的对象先后出现在不同的session中,需要调用update(), saveOrUpdate(), or merge()

Usually update() or saveOrUpdate() are used in the following scenario:

• the application loads an object in the first session

• the object is passed up to the UI tier

• some modifications are made to the object

• the object is passed back down to the business logic tier

• the application persists these modifications by calling update() in a second session

saveOrUpdate() does the following:

• if the object is already persistent in this session, do nothing

 (因为hibernate 可以自动检测持久对象的状态,并持久到数据库中去(事务提交时),所以是do nothing)

• if another object associated with the session has the same identifier, throw an exception

 (记住这个saveOrUpdate方法抛出的异常

• if the object has no identifier property, save() it(如果是临时对象)

• if the object's identifier has the value assigned to a newly instantiated object, save() it

• if the object is versioned by a <version> or <timestamp>, and the version property value is the same value assigned to a newly instantiated object, save() it

(如果object's identifier的值与配置文件中设定的unsaved-value相同 插入新的数据 实际上显式的使用session.save()或者session.update()操作一个对象的时候,实际上是用不到unsaved-value

• otherwise update() the object

 

and merge() is very different:

• if there is a persistent instance with the same identifier currently associated with the session,

copy the state of the given object onto the persistent instance

• if there is no persistent instance currently associated with the session, try to load it from the

database, or create a new persistent instance

• the persistent instance is returned

• the given instance does not become associated with the session, it remains detached

 

如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象的状态覆盖旧有的持久实例

如果session没有相应的持久实例,则尝试从数据库中加载,或创建新的持久化实例,最后返回该持久实例

用户给出的这个对象没有被关联到session上,它依旧是脱管的

重点是最后一句:

当我们使用update的时候,执行完成后,我们提供的对象A的状态变成持久化状态

但当我们使用merge的时候,执行完成,我们提供的对象A还是脱管状态,hibernate或者new了一个B,或者检索到

一个持久对象B,并把我们提供的对象A的所有的值拷贝到这个B,执行完成后B是持久状态,而我们提供的A还是托管状

 

不赞成使用此方法(这个方法的注释上这么说的

@deprecated use {@link org.hibernate.Session#merge(String, Object)}

 

 

小结

1 显式的使用session.save()或者session.update()操作一个对象的时候,

实际上是用不到unsaved-value

2 即使你对临时对象id进行了设置,hibernate也会根据

配置文件设定的主建策略,生成主键,并覆盖程序员设定的值

3 如果你修改了游离对象的id 两种结果一种 抛出org.hibernate.StaleStateException

更新一条不存在的数据抛出异常

另一种更新了修改后id对于那个的记录

4 只有在调用saveOrUpdate方法时 unsaved-value 的配置值先判断是不是save

如果不是save那么就是updade()

5 StaleStateException Thrown when a version number or timestamp check failed, indicating

that the Session contained stale data (when using long transactions

with versioning). Also occurs if we try delete or update a row that

does not exist.

Note that this exception often indicates that the user failed to

specify the correct unsaved-value strategy for a class!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章