Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

//实体A
obj_table{
    `id` bigint(20) NOT NULL,
    `name` varchar(48) NOT NULL,
    ...
    PRIMARY KEY (`id`)
}
//实体B
obj_childObj_table{
    `id` bigint(20) NOT NULL,
    `index` int(11) NOT NULL COMMENT '下标,如1,2,..',
    ...
    PRIMARY KEY (`id`,`index`)
}

B.id = A.id

场景:
A1   A1_B
A2   A2_B
实体对象A1被A2替换,更新所有信息后,需要更新子对象B的信息(A1_B被A2_B替换,但A1_B.id不变)
做法是:直接更新A2_B的id为A1.id   A2_B.setId(A1.id);

结果:
Hibernate抛出异常
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

原因分析:
B.id和B.index构成联合主键,但是在更新A的子对象B时,重新设置了主键B.id 然后updateModel(A2_B);
hibernate不能直接用实体去修改主键,所以抛出异常

可能原因:
a. 网上查到其他可能造成此异常的原因:
当执行更新或删除数据库时,数据库中已不存在这条数据。


b. 此外,之前还猜测是Session一级缓存与数据库不一致造成,更新前使用Session.flush()清除一级缓存 也可以
     session.Clear() 是把一级缓存里面的东西清除掉(保留session) 
     session.Flush(让缓存和数据库当中做到一致)
    但是修改后运行结果异常偶现,涉及Hibernate更新实体原理,学完再来补

解决办法:
正确做法应该是新建一个B对象,拷贝A2_B对象属性,设置id为A1.id;
(旧的A1_B可以删掉或者忽略不管)
    B newB = new B();
    PropertyUtils.copyProperties(newB, A2_B);
    newB.setId(A1.id);
    saveModel(newB);
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值