一个事物下jpa更新数据库实体对象属性后自动update

记录今天偶然发现的一个隐藏的bug

具体是这样的:在一个事物中查询出一条记录例如Student id=1,然后修改student对象的一个属性例如name,再通过jpa执行update 语句修改一个字段age 例如:update student set age = 1 where id=1。最后发现数据库中除了age更新之外,name字段也做了更新,一条update 指令执行了两次update。测试代码如下

service

@Service
@Transactional(readOnly = true)
public class LabelConfigService {

    private ISysLabelConfigRepository iSysLabelConfigRepository;


    @Autowired
    public LabelConfigService(ISysLabelConfigRepository iSysLabelConfigRepository){
        this.iSysLabelConfigRepository = iSysLabelConfigRepository;
     
    }

    @Transactional
    public void testUpdate() {
        SysLabelConfig labelConfig = iSysLabelConfigRepository.findOne(2637);
        labelConfig.setRemark("wlllllllllllll");
        //即使不执行下面的update labelConfig依然会update
        iSysLabelConfigRepository.updateSource(labelConfig.getId(),12);
    }

}

repository

public interface ISysLabelConfigRepository extends JpaRepository<SysLabelConfig,Integer>
        ,JpaSpecificationExecutor<SysLabelConfig> {

    @Modifying
    @Query("update SysLabelConfig set source=?2 where id=?1")
    void updateSource(Integer id, Integer source);
}

test

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ApplicationBootstrap.class)
@WebAppConfiguration
public class TestSysLabelConfig {

    @Autowired
    private LabelConfigService labelConfigService;


    @Test
    public void testUpdate(){
        labelConfigService.testUpdate();

    }



}

执行sql如下

0:24:16.495 [main] INFO  c.c.j.m.s.s.TestSysLabelConfig - Started TestSysLabelConfig in 23.558 seconds (JVM running for 25.682)
Hibernate: select syslabelco0_.id as id1_17_0_, syslabelco0_.create_time as create_t2_17_0_, syslabelco0_.creator as creator3_17_0_, syslabelco0_.label_category as label_ca4_17_0_, syslabelco0_.label_name as label_na5_17_0_, syslabelco0_.label_sub_category as label_su6_17_0_, syslabelco0_.remark as remark7_17_0_, syslabelco0_.source as source8_17_0_ from sys_label_config syslabelco0_ where syslabelco0_.id=?
Hibernate: update sys_label_config set label_category=?, label_name=?, label_sub_category=?, remark=?, source=? where id=?
Hibernate: update sys_label_config set source=? where id=?

实际上即使不执行update语句,修改后的数据库实体对象也会自动更新!!!

解决方法

1.在事物下不要修改实体对象的属性

2.将事物放在repository的接口方法上

ps:在事物中对实体对象的操作要小心,最好不要修改实体对象的属性或者将实体对象转换为vo对象再进行进一步的操作

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值