JPA实体类有Id保存也会新增一条新的数据问题
2019-07-02 16:35
260 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ZuiChuDeQiDian/article/details/95681970
2.看isNew实现
撸了今年阿里、网易和美团的面试,我有一个重要发现.......>>>
前言:沉浸在代码中,没有跳出来看问题就容易钻牛角尖。还是遇见的问题太少。遇见的问题越多,知道的就会越多。
两个不同的实体类深拷贝,然后把id赋值回去更新,会出现一条新数据。
A updateA = DTOMapper.MAPPER.po2po(bAudit); updateA.setId(1) sheetRepository.save(updateA);
1.save方法源码
/* * (non-Javadoc) * @see org.springframework.data.repository.CrudRepository#save(java.lang.Object) */ @Transactional public <S extends T> S save(S entity) { if (entityInformation.isNew(entity)) { em.persist(entity); return entity; } else { return em.merge(entity); } }
在这里说一下,save上spring就已经加了 @Transactional 开启事务的注解。用spring来管理事务就必须开启事务,不然保存不了,因为SET AUTOCOMMIT=0了。
save方法的第一句代码就是判断entity是否是新增还是更新。
2.看isNew实现
第一个是AbstractPersistable提供的,也是我们熟知的 ,根据id是否为空来判断是否是更新
/** * Must be {@link Transient} in order to ensure that no JPA provider complains because of a missing setter. * * @see org.springframework.data.domain.Persistable#isNew() */ @Transient // DATAJPA-622 public boolean isNew() { return null == getId(); }
第二个是 JpaMetamodelEntityInformation提供的
/* * (non-Javadoc) * @see org.springframework.data.repository.core.support.AbstractEntityInformation#isNew(java.lang.Object) */ @Override public boolean isNew(T entity) { if (!versionAttribute.isPresent() || versionAttribute.map(Attribute::getJavaType).map(Class::isPrimitive).orElse(false)) { return super.isNew(entity); } BeanWrapper wrapper = new DirectFieldAccessFallbackBeanWrapper(entity); return versionAttribute.map(it -> wrapper.getPropertyValue(it.getName()) == null).orElse(true); }
这个是是根据version版本号来判断是否是更新,问题就出在这里,我们如果更新,必须更新实体的jpaVersion和数据库里的Version一致,不然就是新增操作。
总结:我一直在各种打印 id有木有赋值进去,刚开始是从对象里get出来的,后来又赋值给一个变量,然后怀疑jpa是不是直接拿自己的属性,而不是拿public方法(id是父类继承下来的),反正折腾了好久。
其实回想一下很简单,但是jpa没有给我报错,我觉得是jpa的不对,哈哈。
相关文章推荐
- j2ee的web项目怎么防止,重复提交的问题?(即点击了提交,后台新增了两条数据,也就是说,其实是点了多次提交,发起了多次http url,这样就插入了多条相同数据,但是主键id是不同的)
- playframework中JPA保存数据的问题
- 新增一条数据后,如何获取刚刚新增数据的ID
- 在Hibernate中新增一条数据,同时获得该数据的id
- EAS WAF1新增单据保存时提示没有数据权限的问题分析。
- sql根据一条数据ID取得上一条和下一条的问题
- 在基于Mybatis持久层框架,使用数据库事务时,插入一条数据后,无法返回主键ID的问题研究
- hibernate学习过程问题(1)--通过代码保存数据时,数据库始终只有一条数据
- sql server中新增一条数据后返回该数据的ID
- sql server中新增一条数据后返回该数据的ID
- Jpa级联数据新增问题
- 解决IE下返回json数据提示文件保存到问题
- extjs4关于proxy中设置idProperty,后store增加数据不能sync()的问题
- Quartz2.x(包括1.x)开发(调度器数据保存在持久层)出现的问题
- 利用django中redisco库,修改redis模型导致数据无法保存以及部分其他问题
- jq 分页展示数据,选中checbox将选中的id保存起来传给后台
- 多并发下数据保存的问题
- 记一次JPA查询分页导致的数据丢失问题
- kafka数据保存时间问题与kafka的性能测试
- JPA保存数据时报持久化对象异常:PersistenceException: org.hibernate.PersistentObjectException