JPA 关于SAVE DELETE

JPA 关于SAVE DELETE

hibernate中持久化对象的生命周期分为三个状态:自由态、持久态和游离态:

  • 自由态的对象只存在于内存,不在数据库里也不再session里;
  • 持久态的对象与session关联并且在数据库中有相应数据;
  • 游离态的对象脱离了session,只存在数据库;

对自由态进行sql语句的操作会将自由态转为持久态,当session清理缓存时持久态会变成游离态。而游离态再被执行sql语句的操作时会变成持久态,如果被delete则会从持久态变成自由态。
然后再说说@Transactional的自动save。我的理解是在服务里进行findbyxx、findall等将持久化对象从游离态转为持久态,当事务结束的时候就会自动再将持久态转 回游离态。就是通过jpa取出来的实体类,对它进行set或者其他的操作,在事务结束时会自动提交并保存到数据库内。

使用spring data jpa时,关于service层一个方法中进行【删除】和【插入】两种操作在同一个事务内处理 执行spring data的delete操作,并不会立即执行,而是等到service方法执行完成,才会提交事务。但是这样的话 insert插入就会出现 重复数据存在,不能重复插入的错误!!!

理一下这个逻辑:【spring的事务@Transactional底层是spring AOP】

  1. 进入方法,开启事务
  2. 代码delete方法是jpa的delete方法,断点在此处发现并没有执行delete的sql语句,但是执行了一条select语句。【可见自定义的delete方法是根据查到的数据再拼接sql在事务提交的时候才执行】
  3. 执行save的插入方法,执行了insert语句,报错数据已经存在,不能重复插入
  4. 关闭事务

解决方案1:

仅更改service代码
手动调用flush()方法,【让jpa在selete出这个对象之后,拼接了delete语句,然后即刻执行sql作用到数据库】,这样在下面insert的时候delete已经执行了,就不会出现重复数据的错误。

解决方案2:

仅改变dao层代码,就是写@Query(“JPQL语句”)
告诉jpa,我要明确执行这条delete的sql语句,避免了【让它去查一遍,拿到实体以后再拼接SQL语句,最后在方法结束,事务提交的时候才去执行delete语句】,这个时候已经迟了。
这个时候是不会执行select语句的,只执行了delete和insert

关于级联关系的删除 https://blog.csdn.net/liyiming2017/article/details/90218062

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值