多行的spring数据jpa更新不起作用

Posted

技术标签:

【中文标题】多行的spring数据jpa更新不起作用【英文标题】:spring data jpa update of multiple rows doesn't work 【发布时间】:2020-03-23 04:38:55 【问题描述】:

前段时间我的查询对于单行更新运行良好。现在我必须修改这个查询来更新多行。该查询是本机的,并使用 postgresql 和 postgis。

旧查询:

@Modifying
@Transactional
@Query(value = "WITH tmp AS (SELECT ST_Difference( (SELECT ST_Buffer(ST_Union(ST_Buffer(a.area\\:\\:geometry, 0.002)), -0.002) \n" + 
        "   FROM mydb.city_area a, mydb.dis_city d, mydb.city c \n" + 
        "   where c.id_city=d.id_city and d.id_dis=?1  \n" + 
        "   and c.cod_city=a.cod_city), \n" + 
        "                     (ST_Difference( ST_GeomFromGeoJSON(?2)\\:\\:geometry, (SELECT ST_Union(a.area\\:\\:geometry) \n" + 
        "   FROM mydb.city_area a, mydb.dis_city d, mydb.city c \n" + 
        "   where c.id_city=d.id_city and d.id_dis=?1  \n" + 
        "   and c.cod_city=a.cod_city and c.full_area=true)                          \n" + 
        "                       ))                                      \n" + 
        "                   ) AS final_area)\n" + 
        "UPDATE mydb.dis_area SET new_area=(SELECT final_area FROM tmp), " +
        "id_type=3 " +
        "WHERE id_dis=?1 ",
        nativeQuery = true)
Integer insertShape(Integer id, String shapeGeoJson);

在新查询中,我在@Modifying 中添加了一些参数,如here 所述:

@Modifying(flushAutomatically = true, clearAutomatically = true)
@Transactional
@Query(value = "WITH tmp AS (SELECT ST_Difference( (SELECT ST_Buffer(ST_Union(ST_Buffer(a.area\\:\\:geometry, 0.002)), -0.002) \n" + 
        "   FROM mydb.city_area a, mydb.dis_city d, mydb.city c \n" + 
        "   where c.id_city=d.id_city and d.id_dis=?1  \n" + 
        "   and c.cod_city=a.cod_city), \n" + 
        "                     (ST_Difference( ST_GeomFromGeoJSON(?2)\\:\\:geometry, (SELECT ST_Union(a.area\\:\\:geometry) \n" + 
        "   FROM mydb.city_area a, mydb.dis_city d, mydb.city c \n" + 
        "   where c.id_city=d.id_city and d.id_dis=?1  \n" + 
        "   and c.cod_city=a.cod_city and c.full_area=true)                          \n" + 
        "                       ))                                      \n" + 
        "                   ) AS final_area)\n" + 
        "UPDATE mydb.dis_area SET new_area=(SELECT final_area FROM tmp), " +
        "id_type=3 " +
        "WHERE id_dis_aree=(select id_dis_aree from dis_area where id_dis=?1) ",
        nativeQuery = true)
Integer insertShape(Integer id, String shapeGeoJson);

但遗憾的是,此更改没有任何效果。 (如果我午餐从 postgresql 查询它运行完美)。 我该如何解决?

编辑: 我添加了查询,但它适用于 postgresql。唯一的区别是旧版本:WHERE id_dis=?1 定位单行,而新版WHERE id_dis_aree=(select id_dis_aree from dis_area where id_dis=?1) 定位多行。 id_dis_areeid_dis 这对夫妇是主键。两条或多条记录可以有相同的id_dis_aree 和不同的id_dis。因此,对于第二个查询,我从id_dis 获取id_dis_aree,以影响更多行。

Edit2:我做了 2 次测试:

    直接用固定的有线 id 值替换最后一个子选择:WHERE id_dis_aree=123456 这样就可以了。这可能是一个解决方案解决方法,获取id_dis_aree 并在调用查询之后。

    用这个替换最后一个子选择:WHERE id_dis_aree IN (select id_dis_aree from dis_area where id_dis=?1) 不起作用。 (备注:子选择总是返回一个值)。

【问题讨论】:

我认为您需要分享您的查询。好吧,如果它太长,把它分成小块。如果它在过去工作,现在它停止工作.. 查询有问题 好的,我明天回去工作时将其发布,但查询在 postgresql 上运行良好(我只更改了 where 子句以捕获更多行)并返回更多更新的行。但是当它在 Spring Boot 上运行时,它返回 0 个更新的行并且没有错误。 select id_dis_aree from dis_area where id_dis=?1 是否会产生多个结果?如果是这样,应该在哪里读 WHERE id_dis_agree IN (select id_dis_aree from dis_area where id_dis=?1) 你应该使用 IN 而不是 = 然后。 @M.Deinum 不,一个结果。 @Accollat​​ivo - 您是否尝试使用 M. Deinum 的使用 IN 的建议?现在错误解决了吗? 【参考方案1】:

我没有找到真正的解决方案,只是一种解决方法:

我通过调用disAreeRepository.findByIdIdDis(idDis).getId().getIdDisAree()@Service中的子查询中获取了值:(select id_dis_aree from dis_area where id_dis=?1)

@Transactional
public Integer insertDis(Integer idDis, String shapeGeoJson) 
    return disAreeRepository.
            insertShape(
                    idDis,
                    shapeGeoJson,
                    disAreeRepository.findByIdIdDis(idDis).getId().getIdDisAree() 
                    );

然后将其作为第三个参数传递给@Repository原生查询:

@Modifying(flushAutomatically = true, clearAutomatically = true)
@Query(value = "WITH tmp AS (SELECT ST_Difference( (SELECT ST_Buffer(ST_Union(ST_Buffer(a.area\\:\\:geometry, 0.002)), -0.002) \n" + 
        "   FROM mydb.city_area a, mydb.dis_city d, mydb.city c \n" + 
        "   where c.id_city=d.id_city and d.id_dis=?1  \n" + 
        "   and c.cod_city=a.cod_city), \n" + 
        "                     (ST_Difference( ST_GeomFromGeoJSON(?2)\\:\\:geometry, (SELECT ST_Union(a.area\\:\\:geometry) \n" + 
        "   FROM mydb.city_area a, mydb.dis_city d, mydb.city c \n" + 
        "   where c.id_city=d.id_city and d.id_dis=?1  \n" + 
        "   and c.cod_city=a.cod_city and c.full_area=true)                          \n" + 
        "                       ))                                      \n" + 
        "                   ) AS final_area)\n" + 
        "UPDATE mydb.dis_area SET new_area=(SELECT final_area FROM tmp), " +
        "id_type=3 " +
        "WHERE id_dis_aree=?3 ",
        nativeQuery = true)
Integer insertShape(Integer id, String shapeGeoJson, Integer idDisAree);

【讨论】:

以上是关于多行的spring数据jpa更新不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 Spring Data JPA 更新实体时@Transactional 隔离级别不起作用?

Spring boot参数更新模型数据库不起作用

Spring Data JPA - 查询日期减去 2 天不起作用

一对多映射不起作用Spring数据JPA

带有 Hibernate 和 Ehcache 的 Spring 数据 JPA 不起作用

LEFT JOIN FETCH 不起作用 - Spring 数据 JPA