java - org.hibernate.hql.internal.QueryExecutionRequestException:不支持不使用休眠的 DML 操作
问题描述
我有一个基于 2.1.0.RELEASE 并使用休眠 5.3.7.Final 与数据库进行最多交互的 Spring Boot 应用程序,除了我想删除对象列表并因此我想执行将该列表作为批量删除的方法。我已经可以使用普通的 hql 查询将 getBulk 作为列表执行,因此我想对删除执行相同的操作,因为它要快得多。
实体是这样创建的:
我有一个表属性,它与一个名为 Value 的表具有一对一的映射关系。值表只有一种关系,即与属性
@Repository
@Entity
@Table(name="ATTRIBUTE")
@OnDelete(action=OnDeleteAction.CASCADE)
public class Attribute implements AttributeInterface {
.......
@OneToOne(cascade=CascadeType.ALL, orphanRemoval=true)
@ElementCollection(fetch=FetchType.EAGER)
@JoinColumn(name="VALUE_ID", nullable=false)
@OnDelete(action=OnDeleteAction.CASCADE)
private Value valueId;
}
来自 postgres :
\d attribute;
Table "public.attribute"
Column | Type | Collation | Nullable | Default
-------------------------+--------------------------+-----------+----------+---------
id | bytea | | not null |
.......
value_id | bigint | | not null |
.......
Indexes:
"attribute_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
.......
"fksc44hph1sm89gdg2o01bjiuad" FOREIGN KEY (value_id) REFERENCES value(id) ON DELETE CASCADE
存储库方法使用@Transactional 和@Modifying 注释显式注释。我的服务类中也有 @Transactional 注释,调用删除。
@Transactional
@Modifying
@Override
public void delete(Collection<byte[]> list) {
try {
Session session = getSessionFactory().openSession();
session.beginTransaction();
session.flush();
session.clear();
String hql_query = "DELETE from Attribute as o WHERE o.id IN (:ids)";
Query<?> query = session.createQuery(hql_query);
query.setParameterList("ids", list);
query.list();
session.getTransaction().commit();
session.close();
} catch (Exception e) {
logger.error("Exception", e);
throw e;
}
}
这给了我错误
java.lang.IllegalStateException: org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations [DELETE from org.Attribute as o WHERE o.id=:ids]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1508)
这个确切的例外在这里和这里都有描述 https://www.javabullets.com/spring-data-jpa-query-not-supported-for-dml-operations/
在整个互联网上,我阅读了我需要的
org.springframework.data.jpa.repository.Modifying
注解。我必须添加额外的依赖项,即 spring-data-jpa 工件,因为我没有 Modifying 注释。IE
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
好吧,我现在确实拥有它,但仍然不允许删除查询。
如果我稍微更改代码并使用休眠来删除行,那么一切正常,但在这种情况下这不是一个骗局删除,而且速度很慢。即,如果我将整个属性作为对象传递,并在集合端直接调用休眠会话时为每个循环执行一次,那么它就可以工作。
session.delete(attribute);
session.getTransaction().commit();
session.close();
我的问题是我在删除批量方法中做错了什么。我在这里有什么遗漏吗?
解决方案
这与Modifying
. Modifying
是一个 Spring Data 注释,但你似乎没有使用 Spring Data。
您正在执行query.list()
用于执行返回结果的选择语句。
由于您正在尝试执行删除,因此您需要使用executeUpdate()
JavaDoc 指出:
执行更新或删除语句。
推荐阅读
- swagger - Loopback 4 中的 Swagger - 使用 @property 装饰器来表示嵌套对象
- css - 如何在一个带有borderRadius的视图组件内安装两个视图组件?
- gradle - Gradle:未找到 thorntail 插件
- html - 如何按高度对齐卡片组内的所有图像?
- docker - 是否可以在 Docker 的一个构建步骤中添加、运行和删除安装程序?
- pandas - 对数据框 df 中月份列从 1 月到 12 月的月份进行排序
- python - 如何为包含小数和科学记数法的字符串创建 list.sort() 键?
- java - 通过调试找到日志文件路径?
- elasticsearch - Elasticsearch 使用地理位置参数过滤“应该”结果
- mysql - 如何使用具有匹配列对的行数更新列?