问题遇到的现象和发生背景
学校项目出了一个问题,老师让我们优化
Spring data jpa 中 save 方法
①在更新的时候会先select 然后判断 再 update
②更新会覆盖所有字段,即使你没更新某个字段,那么该字段会被改成null
用代码块功能插入代码,请勿粘贴截图
SimpleJpaRepository.save 源码
@Transactional
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null.");
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
entityInformation.isNew(entity)是用来判断插入的,但是这个merge一定会先select,搞的我很头疼
运行结果及报错内容
我的解答思路和尝试过的方法
我尝试重写save
@Override
@Transactional
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null.");
if (entityInformation.isNew(entity)) {
em.persist(entity);
} else {
Session session = em.unwrap(Session.class);
session.update(entity);
}
return entity;
}
这样解决会select的问题,但是更新null字段仍然存在
想到了@Column(updatable = false)能够避免更新
我在运行过程中动态加入注解并修改.class文件
class文件中确实会出现新的注解,并且在下一次运行时有效
ClassPool aDefault = ClassPool.getDefault();
addAnnotation(className,attributeName,typeName);
//使用类的全类名
CtClass ctClass = aDefault.get(className);
//获取当前项目系统路径
File file = new File(".");
//找到class文件地址
String canonicalPath = file.getCanonicalPath() + "target所在地址";
System.out.println(canonicalPath);
byte[] bytes = ctClass.toBytecode();
//写入到文件夹 --->这样就可以修改编译之后的class文件了
FileOutputStream fileOutputStream = new FileOutputStream(canonicalPath);
fileOutputStream.write(bytes);
fileOutputStream.close();
我想要达到的结果
但是修改完后本次仍无效果,我猜jpa应该在容器初始化时就固定了,大佬们给点宝贵意见