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`这三个方法都是用于更新或保存实体对象到数据库中的,但它们之间存在着重要的区别,这些区别主要体现...
`saveOrUpdate`是Hibernate提供的一种便捷方法,用于处理对象的保存或更新操作。在深入讲解`saveOrUpdate`之前,我们先理解一下Hibernate的基本概念。 在Hibernate中,实体类(Entity Class)代表数据库中的表,...
在Java的持久化框架Hibernate中,管理对象与数据库之间的交互是通过一系列的方法完成的,其中包括`save()`, `saveOrUpdate()`, `persist()`, `merge()`, 和 `update()`。这些方法各有其特点和适用场景,理解它们的...
`saveOrUpdate`是Hibernate提供的一个便捷方法,它的主要作用是根据对象当前的状态来决定执行`save()`还是`update()`操作。具体来说: - 如果对象是瞬时状态,`saveOrUpdate`会调用`save()`,为对象生成一个新的...
### Hibernate中的`save()`与`saveOrUpdate()`方法详解 #### 一、概述 在Java持久化框架Hibernate中,`save()`与`saveOrUpdate()`是非常重要的两个方法,它们用于处理对象的持久化操作。理解这两个方法的工作原理...
本文将详细介绍Hibernate持久层中的一些核心方法,包括`session.load`, `session.find`, `session.iterator`, `session.save`, `session.update`, `session.saveorupdate`。 1. `session.load()`: - `load()`方法...
- **创建(Create)**:使用Session的save()或saveOrUpdate()方法将对象持久化到数据库中。 - **读取(Read)**:通过Session的get()或load()方法获取对象,或者使用Query或Criteria API来执行查询操作。 - **...
例如,使用 `save()` 或 `saveOrUpdate()` 方法保存对象,`get()` 或 `load()` 方法获取对象,`update()` 更新对象,以及 `delete()` 删除对象。同时,Session 提供了事务管理能力,可以确保数据操作的原子性和一致...
学习完基础后,可深入研究Hibernate的高级特性,如 Criteria API、Hibernate Search 和 JPA 规范等。 总之,"hibernate第一个hibernate"项目是一个绝佳的起点,它将引导你了解并掌握Hibernate的基本概念和操作。...
在Java持久化框架Hibernate中,HibernateTemplate是一个便捷的工具类,它封装了常见的数据库操作,使得开发者能够更方便地与数据库交互。以下是对标题和描述中提到的HibernateTemplate方法的详细总结: A. `get` 和...
Session提供了操作实体的方法,如`save()`, `saveOrUpdate()`, `update()`, `delete()`等。例如,`save()`方法用来持久化新对象,`saveOrUpdate()`判断对象是否已存在,如果不存在则保存,否则更新,`update()`更新...
《Hibernate3.3_学习笔记》是一份详细记录了Hibernate3.3版本特性和使用方法的文档,旨在帮助开发者深入理解和应用这一强大的对象关系映射(ORM)框架。Hibernate是Java开发中的一个明星库,它简化了数据库操作,...
- 创建(Create):使用Session的save()或saveOrUpdate()方法保存实体到数据库。 - 读取(Read):利用Session的get()或load()方法根据ID获取实体,query()方法用于执行HQL(Hibernate Query Language)查询。 - ...
1. 增加(Insert):在Hibernate中,我们可以通过Session的`save()`或`saveOrUpdate()`方法来保存新对象到数据库。在Spring整合中,通常会在Service层调用DAO层的方法,如`userRepository.save(user)`。 2. 删除...
例如,`Session`接口是主要的持久化工作接口,使用`save()`或`saveOrUpdate()`方法保存实体,`load()`或`get()`方法加载实体,`update()`更新实体,`delete()`删除实体。 5. **查询语言HQL**:Hibernate Query ...
2. Save/Update/Delete:Session提供了对实体的增删改操作,如save(), saveOrUpdate(), update(), delete()。 3. Flush:Session会定期或者在某些操作后自动将内存中的改变同步到数据库,也可以手动调用flush()方法...
当调用此方法时,Hibernate会生成一条SQL UPDATE语句来更新该对象对应数据库表中的记录。如果对象已经是持久化状态,则直接对其进行修改即可,无需显式调用`update`方法。 #### 三、update 和 saveOrUpdate 区别 -...
- **创建(Create)**:使用Session的`save()`或`saveOrUpdate()`方法保存新对象到数据库。 ```java User user = new User("John Doe"); session.save(user); ``` - **读取(Read)**:通过Session的`get()`...