`
poethelasi
  • 浏览: 6067 次
文章分类
社区版块
存档分类
最新评论

Hibernate 专题研究系列(一) save/update/saveOrUpdate等方法学习(续一)

阅读更多

 

1、save      
1)返回值
Serializable
 
2)事件监听处理类及重要代码
  DefaultSaveEventListener  
public class DefaultSaveEventListener extends DefaultSaveOrUpdateEventListener {
 
     protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
            // this implementation is supposed to tolerate incorrect unsaved-value
            // mappings, for the purpose of backward-compatibility
           EntityEntry entry = event.getSession().getPersistenceContext().getEntry( event.getEntity() );
            if ( entry!= null && entry.getStatus() != Status.DELETED ) {  //这里将游离态实体当做瞬时态再插入一遍
                 return entityIsPersistent(event);
           }
            else {
                 return entityIsTransient(event);
           }
     }
}
 
3)事务范围外的处理方式
3.1)Connection设置事务为自动提交时,且ID由数据库自动生成的,save会立即执行插入操作,并自动提交事务,数据库中有数据;
3.2)Connection设置事务为自动提交时,且ID由数据库自动生成的,如果不手动开启/提交事务,save操作会立即执行,但是不会提交事务,所以数据库没有数据。
如果手动开启事务/提交事务,save操作会立即执行,当提交事务时,将更新提交至数据库。
 
4)游离态
如果一个游离态的实体,再次使用save方法,将不会更新原来的对象,只会在数据库中重新再插入一条,执行规则遵循3.1)和 3.2)。
 
5)持久态
如果一个持久态的实体,再次使用save方法,将不会执行数据库操作,只会做一些数据验证,并返回唯一ID。
 
6)瞬时态
如果一个瞬时态的实体,执行save方法,将会在数据库中插入一条记录。
 
7)总结
7.1)save不区分游离态和瞬时态,它把游离态作为瞬时态处理。
7.2)如果ID列不是由数据库自动生成的,而是由编程管理并生成的(不管是手动赋值Assigned,还是使用UUID,GUID等策略),save操作都会不立即执行。
7.3)只有EntityIdentityInsertAction才有可能会延迟执行,EntityInsertAction永远都是延迟执行的。迟延执行指的是手动提交事务才到数据
    库执行,无事务情况下就没办法提交更新了。
源码:
     private AbstractEntityInsertAction addInsertAction(
                Object[] values,
                Serializable id,
                Object entity,
                EntityPersister persister,
                 boolean useIdentityColumn,
                EventSource source,
                 boolean shouldDelayIdentityInserts) {
            if ( useIdentityColumn ) {
                EntityIdentityInsertAction insert = new EntityIdentityInsertAction(
                           values, entity, persister, isVersionIncrementDisabled(), source, shouldDelayIdentityInserts
                );
                source.getActionQueue().addAction( insert );
                 return insert;
                
                // EntityIdentityInsertAction 有可能为true
                // public boolean isEarlyInsert () {
                   //           return ! isDelayed;
                // }
           }
            else {
                Object version = Versioning. getVersion( values, persister );
                EntityInsertAction insert = new EntityInsertAction(
                           id, values, entity, version, persister, isVersionIncrementDisabled(), source
                );
                source.getActionQueue().addAction( insert );
                 return insert;
 
                // EntityInsertAction 永远返回false
                //  public boolean isEarlyInsert() {
                   //            return false;
                //   }
           }
     }
 
2、update
1)返回值
void
 
2)事件监听处理类及重要代码
DefaultUpdateEventListener  
protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
     // this implementation is supposed to tolerate incorrect unsaved-value
     // mappings, for the purpose of backward-compatibility
     EntityEntry entry = event.getSession().getPersistenceContext().getEntry( event.getEntity() );
     if ( entry!=null ) {
            if ( entry.getStatus()== Status.DELETED ) {
                 throw new ObjectDeletedException( "deleted instance passed to update()", null, event.getEntityName() );
           }
            else {
                 return entityIsPersistent(event);
           }
     }
     else {
            entityIsDetached(event);
            return null;
     }
}
 
3)事务范围外的处理方式
   非立即执行
 
4)瞬时态
注意上面代码,没有瞬时态的处理部分,瞬时态被当做游离态处理,执行entityIsDetached(event)方法;结果是如果update一个瞬时态的对象,提交事务时,数据库中
是不会执行插入操作(insert)的,执行的还是更新操作(update),所以会抛出异常。因为entityIsDetached(event)方法会将瞬时态转为持久态,但是该数据在数据库中
是不存在的,update操作期望更新一条记录,但是更新返回的结果却是0,所以程序将会抛出异常。
 
5)游离态
update只是将瞬时态转为持久态或游离态转为持久态,并在PersistenceContext持久化上下文中加入EntityEntry;只有等到提交事务时,执行Flush操作,才会从
PersistenceContext中将所有需要更新的实体,为之在ActionQueue中添加相应的更新操作(EntityUpdateAction),然后依次执行。
 
6)持久态
如果一个持久态的实体,将不会执行数据库操作,只会做一些数据验证,并返回唯一ID。
 
7)总结
7.1)更新操作不会插入数据
7.2)更新操作不会立即执行
 
3、saveOrUpdate
1) 返回值
  void
 
2)事件监听处理类及重要代码
DefaultSaveOrUpdateEventListener    
protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
     EntityState entityState = getEntityState(
                event.getEntity(),
                event.getEntityName(),
                event.getEntry(),
                event.getSession()
     );
 
     switch ( entityState ) {
            case DETACHED:
                 entityIsDetached( event );
                 return null;
            case PERSISTENT:
                 return entityIsPersistent( event );
            default: //TRANSIENT or DELETED
                 return entityIsTransient( event );
     }
}
 
3)事务范围外的处理方式
   由于saveOrUpdate方法与save方法的相似性,所以是否立即执行或者事务管理方面是一样的。见save方法。
 
4) 瞬时态
   与save方法一致。
 
5)游离态
   与update方法一致。
 
6)持久态
   与save方法一致。
 
7)总结
7.1) save方法存在一个问题:save游离态实体时,不会更新数据库中相应的对象,而是重新插入一条记录;因为save将游离态看做瞬时态;
7.2) update方法存在一个问题:update瞬时态实体时,不会在数据库中插入一条数据,而是会抛出异常;因为update将瞬时态看做游离态,
     数据库中并没有与之相应的数据记录,只是在持久化上下文中将该实体看做持久态,等到事务提交时,本来希望更新数据库一条记录,
     实际上更新的结果为0,所以会抛出异常。
7.3) 正是由于save和update方法存在的问题,所以saveOrUpdate方法解决了上述两个方法存在的问题。saveOrUpdate将对实体状态进行细分,
分为游离态、持久态、瞬时态;所以游离态不会被当做瞬时态处理,执行真正的update方法,而不是save方法;瞬时态也不会被当做游离态处理,
执行真正的save方法,而不是update方法。
7.4)从本质上说(代码的角度),saveOrUpdate方法与save方法的处理逻辑是基本一致的,只是对待实体状态时的区分逻辑有所不同;
saveOrUpdate将实体状态分为游离态、持久态、瞬时态,并做相应的处理,以便更正确的执行相应操作;
save只分为持久态和瞬时态,将游离态看做的瞬时态,所以这是save方法导致问题的根本所在。
7.5)正是由于saveOrUpdate方法与save方法的相似性,所以是否立即执行或者事务管理方面是一样的。见save方法。

 

分享到:
评论

相关推荐

    Hibernate merge、update与saveOrUpdate方法的区别

    ### Hibernate merge、update与saveOrUpdate方法的区别 在Hibernate框架中,`merge`、`update`与`saveOrUpdate`这三个方法都是用于更新或保存实体对象到数据库中的,但它们之间存在着重要的区别,这些区别主要体现...

    hibernate 的saveOrUpdate

    `saveOrUpdate`是Hibernate提供的一种便捷方法,用于处理对象的保存或更新操作。在深入讲解`saveOrUpdate`之前,我们先理解一下Hibernate的基本概念。 在Hibernate中,实体类(Entity Class)代表数据库中的表,...

    05_传智播客hibernate教程_实体对象的三种状态与saveOrUpdate方法

    `saveOrUpdate`是Hibernate提供的一个便捷方法,它的主要作用是根据对象当前的状态来决定执行`save()`还是`update()`操作。具体来说: - 如果对象是瞬时状态,`saveOrUpdate`会调用`save()`,为对象生成一个新的...

    save, saveOrUpdate, persist, merge, update 区别.docx

    在Java的持久化框架Hibernate中,管理对象与数据库之间的交互是通过一系列的方法完成的,其中包括`save()`, `saveOrUpdate()`, `persist()`, `merge()`, 和 `update()`。这些方法各有其特点和适用场景,理解它们的...

    Hibernate save() saveorupdate()的用法第1/2页

    ### Hibernate中的`save()`与`saveOrUpdate()`方法详解 #### 一、概述 在Java持久化框架Hibernate中,`save()`与`saveOrUpdate()`是非常重要的两个方法,它们用于处理对象的持久化操作。理解这两个方法的工作原理...

    Hibernate持久层方法汇总

    本文将详细介绍Hibernate持久层中的一些核心方法,包括`session.load`, `session.find`, `session.iterator`, `session.save`, `session.update`, `session.saveorupdate`。 1. `session.load()`: - `load()`方法...

    Hibernate3框架系列 [ 1 ]

    - **创建(Create)**:使用Session的save()或saveOrUpdate()方法将对象持久化到数据库中。 - **读取(Read)**:通过Session的get()或load()方法获取对象,或者使用Query或Criteria API来执行查询操作。 - **...

    hibernate 重点知识原创

    例如,使用 `save()` 或 `saveOrUpdate()` 方法保存对象,`get()` 或 `load()` 方法获取对象,`update()` 更新对象,以及 `delete()` 删除对象。同时,Session 提供了事务管理能力,可以确保数据操作的原子性和一致...

    hibernate第一个hibernate

    学习完基础后,可深入研究Hibernate的高级特性,如 Criteria API、Hibernate Search 和 JPA 规范等。 总之,"hibernate第一个hibernate"项目是一个绝佳的起点,它将引导你了解并掌握Hibernate的基本概念和操作。...

    Hibernate方法总结

    在Java持久化框架Hibernate中,HibernateTemplate是一个便捷的工具类,它封装了常见的数据库操作,使得开发者能够更方便地与数据库交互。以下是对标题和描述中提到的HibernateTemplate方法的详细总结: A. `get` 和...

    hibernate常用方法集合

    Session提供了操作实体的方法,如`save()`, `saveOrUpdate()`, `update()`, `delete()`等。例如,`save()`方法用来持久化新对象,`saveOrUpdate()`判断对象是否已存在,如果不存在则保存,否则更新,`update()`更新...

    Hibernate3.3_学习笔记.doc.zip

    《Hibernate3.3_学习笔记》是一份详细记录了Hibernate3.3版本特性和使用方法的文档,旨在帮助开发者深入理解和应用这一强大的对象关系映射(ORM)框架。Hibernate是Java开发中的一个明星库,它简化了数据库操作,...

    Hibernate学习笔记第一次课

    - 创建(Create):使用Session的save()或saveOrUpdate()方法保存实体到数据库。 - 读取(Read):利用Session的get()或load()方法根据ID获取实体,query()方法用于执行HQL(Hibernate Query Language)查询。 - ...

    spring hibernate整合的底层数据操作方法

    1. 增加(Insert):在Hibernate中,我们可以通过Session的`save()`或`saveOrUpdate()`方法来保存新对象到数据库。在Spring整合中,通常会在Service层调用DAO层的方法,如`userRepository.save(user)`。 2. 删除...

    hibernate_reference中文/英文.pdf

    例如,`Session`接口是主要的持久化工作接口,使用`save()`或`saveOrUpdate()`方法保存实体,`load()`或`get()`方法加载实体,`update()`更新实体,`delete()`删除实体。 5. **查询语言HQL**:Hibernate Query ...

    Hibernate学习笔记(培训学习时的笔记)

    2. Save/Update/Delete:Session提供了对实体的增删改操作,如save(), saveOrUpdate(), update(), delete()。 3. Flush:Session会定期或者在某些操作后自动将内存中的改变同步到数据库,也可以手动调用flush()方法...

    hibernate的各种保存方式的区别

    当调用此方法时,Hibernate会生成一条SQL UPDATE语句来更新该对象对应数据库表中的记录。如果对象已经是持久化状态,则直接对其进行修改即可,无需显式调用`update`方法。 #### 三、update 和 saveOrUpdate 区别 -...

    Hibernate基本实现

    - **创建(Create)**:使用Session的`save()`或`saveOrUpdate()`方法保存新对象到数据库。 ```java User user = new User("John Doe"); session.save(user); ``` - **读取(Read)**:通过Session的`get()`...

Global site tag (gtag.js) - Google Analytics