骑母猪去兜风 2022-12-07 12:19 采纳率: 100%
浏览 158
已结题

jpa save先select后update且默认更新所有字段的问题

问题遇到的现象和发生背景

学校项目出了一个问题,老师让我们优化
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();

img

我想要达到的结果

但是修改完后本次仍无效果,我猜jpa应该在容器初始化时就固定了,大佬们给点宝贵意见

  • 写回答

2条回答 默认 最新

查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 12月19日
  • 专家已采纳回答 12月11日
  • 修改了问题 12月7日
  • 创建了问题 12月7日

悬赏问题

  • ¥15 依据报错在原代吗格式的基础上解决问题
  • ¥15 在虚拟机中安装flash code
  • ¥15 单片机stm32f10x编写光敏电阻调节3.3伏大功率灯亮度(光强越大灯越暗,白天正常光强灯不亮,使用ADC,PWM等模块)望各位找一下错误或者提供一个可实现功能的代码
  • ¥20 verilog状态机方法流水灯
  • ¥15 pandas代码实现不了意图
  • ¥15 GD32H7 从存储器到外设SPI传输数据无法重复启用DMA
  • ¥25 LT码在高斯信道下的误码率仿真
  • ¥45 渲染完成之后将物体的材质贴图改变,自动化进行这个操作
  • ¥15 yolov5目标检测并显示目标出现的时间或视频帧
  • ¥15 电视版的优酷可以设置电影连续播放吗?