关于SpringDataJpa使用@Queue自定义查询语句的坑

今天遇到一个坑,很是奇葩,做个记录,也希望可以帮到大家,或者哪位大佬指出问题错在。

问题描述:Jpa中使用@Queue注解进行update操作,感觉没有命中数据库,返回值始终不正确

解决方案:使用findById搭配save进行更新语句---->也就是先查询,后修改

如果有兴趣的,可以继续往下看

第一部分:数据库运行,试水

这里可以看到我们运行 update my_order set is_dispose = 1 where id = 14805531574272 这条Sql语句的影响行数是 0

因为我们之前就已经运行过这条Sql语句了,此时的数据库的字段is_dispose已经是1了,所以影响的行数是0

--------> 试水成功

第二部分:创建本地接口

那么接下来我创建了一个接口,就是用于修改是否处理的,如下:


    @Modifying(flushAutomatically = true,clearAutomatically = true)
    @Query(value = "update my_order set is_dispose = 1 where id = ?1",nativeQuery = true)
    Integer updMyOrderById(@Param("id")Long id);

我先介绍一下这几个注解:

@Modifying(flushAutomatically = true,clearAutomatically = true)

@Modifying:Jpa使用@Queue的时候需要加上该注解

   flushAutomatically:表示在执行@Queue中的语句的时候(也就是更新或者删除)会刷新该对应的实体类(应该会去查询)

   clearAutomatically:这个就是表示在执行以后会刷新

nativeQuery = true:表示本地执行Sql语句,也就是说是原生的Sql语句,就相当于是把我们写的sql语句复制到数据库跑

第三部分:Debug运行

如图,可以看到我们使用的ID还是用一个ID,也就是14805531574272 但是我们受影响的行数居然赫然是1     那这样不行啊,这会影响到程序的结果的,那这样我们就不会抛出异常,程序就不会回滚,这是一个很严肃的事情

这是怎么回事呢?说实话我现在都还不知道,所以只好开启百度模式,于是我发现了另外两个注解:

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@DynamicInsert   // ----> 就是这两个
@DynamicUpdate   // ----> 就是这两个
public class MyOrder {

那么这两个注解是干嘛的?

@DynamicInsert :表示会在执行Insert的时候创建一个动态的sql语句,也就是说只要是数据是null的就不会添加到Sql语句中
@DynamicUpdate :同理,就是在Update的时候如果是null也不会添加到Sql语句中

还别说哈,问题没解决,又发现了新大陆呢。

所以到现在我还没发现是怎么回事?那只好另辟蹊径换一种方式进行update

第四部分:使用save搭配findById进行更新语句

    @Override
    @Transactional
    public List<Jackpot> saveAllJackpot(List<Jackpot> jackpots, Long id) {
        List<Jackpot> newJackpots = jackpotRepo.saveAll(jackpots);
        Assert.notEmpty(newJackpots, "绑定多条奖项失败");
        MyOrder myOrder = myOrderRepo.findById(id).get();
        if (myOrder.getIsDispose()) {
            throw new IllegalArgumentException("订单已处理");
        }
        myOrder.setIsDispose(true);
        MyOrder save = myOrderRepo.save(myOrder);
        Assert.notNull(save, "更新订单状态失败");
        return newJackpots;
    }

对的,就是采用这种笨拙的方式进行更新,首先我们在更新之前先根据id查询出来该对象信息。然后进行判断对象信息,如果对象的isDispose为true那就代表这个订单已经被处理了,那么就不会执行后面的save更新语句,如果不是true就代表还没处理该订单,那么我们就把状态赋值为true,在执行save修改订单,这样就达到了我的业务需求。

结语:到这里基本上就结束了,在这里谢谢大家花费宝贵的时间点开这篇文章并且看到了这里,目前针对之所以出现上诉问题,个人感觉是我使用@Queue执行Update语句的时候没有命中数据库,所以每次都会出现返回值不正确的原因,至于为啥会出这个为题的原因我也不清楚,我也还只是个Jpa的小白,我甚至hibernate都没有学习过,如果有哪位大佬路过,欢迎评论区指出~~

~~~谢谢大家的观看

发布了25 篇原创文章 · 获赞 9 · 访问量 3060

猜你喜欢

转载自blog.csdn.net/qq_40053836/article/details/98872661