Hibernate saveOrupdate 更新一列数据()更新数据问题

hibernate使用update或者saveOrupdate更改数据时需要注意
用这两者更改数据的时候,注意更改的不只是表单中的其中一个字段的数据,如果提供的实体类,两个数据都是和表中的数据不一样,那么就有可能会把其中的两个数据都该掉,当然如果使用saveOrupdate还有可能会出现新加一条数据的情况。之前为了避免新加数据,曾采用过以下方式
this.getSession().clear();
this.getHibernateTemplate().saveorUpdate(company);
但这种方法也很奇怪,用的时候有时候灵有时候不灵。
后来的一次,本来只想改变一条数据,但是由于表中的其它字段数据都是相似的,有的两条数据就只有一个或者两个字段不一样,这种情况用update更改数据,很有可能会把其中的一个数据改成另一种相似数据了。这样就很不好了,后来找到了办法,如下
String hql="update ResumeToJob set
status="+resumeToJob.getStatus()+" where &
& &uId="+resumeToJob.getuId()+"
and jobId="+resumeToJob.getJobId();
this.getHibernateTemplate().bulkUpdate(hql);
这种办法就是为了保证只更改status数据,而不要改动其他的。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。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);
return entityIsTransient(event);
3)事务范围外的处理方式
3.1)Connection设置事务为自动提交时,且ID由数据库自动生成的,save会立即执行插入操作,并自动提交事务,数据库中有数据;
3.2)Connection设置事务为非自动提交时,且ID由数据库自动生成的,如果不手动开启/提交事务,save操作会立即执行,但是不会提交事务,所以数据库没有数据。
如果手动开启事务/提交事务,save操作会立即执行,当提交事务时,将更新提交至数据库。
如果一个游离态的实体,再次使用save方法,将不会更新原来的对象,只会在数据库中重新再插入一条,执行规则遵循3.1)和 3.2)。
如果一个持久态的实体,再次使用save方法,将不会执行数据库操作,只会做一些数据验证,并返回唯一ID。
如果一个瞬时态的实体,执行save方法,将会在数据库中插入一条记录。
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 );
// EntityIdentityInsertAction 有可能为true
// public boolean isEarlyInsert () {
return ! isDelayed;
Object version = Versioning. getVersion( values, persister );
EntityInsertAction insert = new EntityInsertAction(
id, values, entity, version, persister, isVersionIncrementDisabled(), source
source.getActionQueue().addAction( insert );
// EntityInsertAction 永远返回false
public boolean isEarlyInsert() {
return false;
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() );
return entityIsPersistent(event);
entityIsDetached(event);
return null;
3)事务范围外的处理方式
非立即执行
注意上面代码,没有瞬时态的处理部分,瞬时态被当做游离态处理,执行entityIsDetached(event)方法;结果是如果update一个瞬时态的对象,提交事务时,数据库中
是不会执行插入操作(insert)的,执行的还是更新操作(update),所以会抛出异常。因为entityIsDetached(event)方法会将瞬时态转为持久态,但是该数据在数据库中
是不存在的,update操作期望更新一条记录,但是更新返回的结果却是0,所以程序将会抛出异常。
update只是将瞬时态转为持久态或游离态转为持久态,并在PersistenceContext持久化上下文中加入EntityEntry;只有等到提交事务时,执行Flush操作,才会从
PersistenceContext中将所有需要更新的实体,为之在ActionQueue中添加相应的更新操作(EntityUpdateAction),然后依次执行。
如果一个持久态的实体,将不会执行数据库操作,只会做一些数据验证,并返回唯一ID。
7.1)更新操作不会插入数据
7.2)更新操作不会立即执行
3、saveOrUpdate
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方法。
与save方法一致。
与update方法一致。
与save方法一致。
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方法。
poethelasi
浏览: 1660 次
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'厚积薄发,樯橹灰飞烟灭
hibernate4saveorUpdate更新也会插入
最近使用saveOrUpdate的时候,发现一直不更新数据。
按文档上说明应该是:
当数据有Id的时候就进行更新,但是结果没有
今天具体研究了一下,saveOrUpdate其实不是针对于数据本身(Id),
而是对象,可以理解为:有新对象则插入,已有对象就更新。
所以想要达到更新效果,自然需要用从数据库查询出来的对象了
private OrderDao orderD
@Transactionalpublic void updateOrder(Order order) {orderDao.saveOrUpdate(order);
//此时会新添加一条数据
@Transactionalpublic void updateOrder(Order order) {
Order neworder =orderDao.getEntity(order.getId);
neworder.setOrderNo(order.getOrgerNo);orderDao.saveOrUpdate(neworder);//neworder是查询出来的对象,去修改neworder的时候,就会去更新数据
这个问题是比较容易被忽略的问题了
如果这篇文章对您有所帮助,记得关注我喔
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!hibernate save和update以及saveOrUpdate区别
save()方法很显然是执行保存操作的,如果是对一个新的刚new出来的对象进行保存,自然要使用这个方法了,中没有这个对象。
update()如果是对一个已经存在的托管对象进行更新那么肯定是要使用update()方法了,数据中有这个对象。
saveOrUpdate()这个方法是更新或者插入,有主键就执行更新,如果没有主键就执行插入。
区别:对于一个从托管状态到瞬态的对象(对于一个从数据库中取出来又被删除的对象),这个对象本身是有主键的,但是因为被删除了,所以这个时候因为数据库中已经没有了这条记录了。不过它还有主键存在,所以这个时候不可以使用update()或者是saveOrUpdate(),因为update()方法是认为数据库中肯定有这条记录的,而saveOrUpdate的执行过程就是先查看这个对象是不是有主键,有主键那么就执行update()方法,没有主键就执行save()方法,因此结果跟调用了update()方法的效果是一样的,结果就会出错,因为这个对象已经被删除了,数据库中已经没有这条记录了,只是它还有主键而已(仅仅是存在于内存中),因此这个时候要执行的是save()方法。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!10:50 提问
getHibernateTemplate().saveOrupdate() 可以插入却无法更新
换成merge()方法时刻更新的 ,这是什么问题,这个问题网上也搜索了好多,也没解决掉我的问题
按赞数排序
对象的主键为空,或找不都主键对应的记录
或者你没有删掉权限去更新了?
遇到过这个问题。因为调用了同一个引用。 我是在更新前加了刷新flush解决的。 不知道适不适合你,你可以试试。
调用merge是可以更新的,这是什么原因,困扰了我很久,一直没解决
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐}

我要回帖

更多关于 update多表更新数据 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信