JPA Native 查询为 INSERT INTO VALUES 中的 List 参数放置括号错误

Posted

技术标签:

【中文标题】JPA Native 查询为 INSERT INTO VALUES 中的 List 参数放置括号错误【英文标题】:JPA Native query puts parentheses wrong for List paremeter on INSERT INTO VALUES 【发布时间】:2019-10-02 14:54:42 【问题描述】:

所以我试图为 JPA (JPQL) 编写一个本地命名查询到 INSERT 多行数据,并取回插入记录的所有 id(与唯一约束不冲突)首要的关键)。我正在使用 Postgres 数据库。

数据库如下所示:SELECT * FROM table;

id | sent
---+------
1  | f
(1 row)

我想要实现的是这个 PSQL 语句:

INSERT INTO table VALUES (1, false),(2, false) ON CONFLICT DO NOTHING RETURNING id;

应该返回:

id
---
2
(1 row)

所以我最初的想法是在 JPA 中进行原生查询:

@Repository
interface NotificationRepository : JpaRepository<Foo, Int> 

    @Modifying
    @Query("INSERT INTO Foo VALUES (:foos) ON CONFLICT DO NOTHING RETURNING id", nativeQuery = true)
    fun addAllAndReturnInserted(foos: List<Foo>): List<Int>

这适用于列表中的一个值,但对于多个值,它将创建如下查询:

Hibernate: INSERT INTO Foo VALUES (?, ?) ON CONFLICT DO NOTHING RETURNING id

它会抛出异常:

PSQLException: ERROR: column "sent" is of type boolean but expression is of type int

有没有办法将列表转换为单独的括号,例如 (?), (?) 而不是一个 (?, ?) ??

【问题讨论】:

你不能用列表来做到这一点。 Hibernate 无法知道您在本机查询中尝试为您拆分列表的意思。你可以有INSERT INTO table VALUES (?, ?) ON CONFLICT DO NOTHING RETURNING id @coladict 你对如何构建我的问题中描述的查询有其他建议吗? 【参考方案1】:

不,您的想法很好,但不适用于 Spring Data,因为:

    列表参数扩展仅作为逗号分隔的数据值列表发生(a, b, ...),而不是记录或行列表(a), (b), (...) 也不支持返回某些内容的数据修改语句(目前):https://jira.spring.io/browse/DATAJPA-1389

但是,至少有一个解决方法可以解决这里描述的批处理问题:

How to do bulk (multi row) inserts with JpaRepository?

【讨论】:

以上是关于JPA Native 查询为 INSERT INTO VALUES 中的 List 参数放置括号错误的主要内容,如果未能解决你的问题,请参考以下文章

MySQL - INSERT 查询需要很长时间

Hibernate,JPA注解@DynamicInsert和@DynamicUpdate

在 Play JPA 项目中使用 sbt-native-packager 将自定义文件夹添加到 Docker

如何在使用JPA的INSERT中处理空值?

jpa@query 可以写insert 吗

Spring Data JPA native query 分页