【发布时间】:2019-05-03 22:17:32
【问题描述】:
我有一个基于 2.1.0.RELEASE 并使用 hibernate 5.3.7.Final 进行最多交互的 Spring Boot 应用程序 到数据库,除了我想删除对象列表的几种情况,因此我想执行一个方法将该列表作为批量删除。我已经可以使用普通的 hql 查询将 getBulk 作为列表执行,因此 我想对删除也一样,因为它要快得多。
实体是这样创建的:
我有一个表属性,它一对一映射到名为值的表。 值表只有一个关系,即与属性
@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 注释。即
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
嗯,我现在有,但仍然没有 允许删除查询。
如果我稍微更改代码并使用休眠来删除行,那么一切正常,但在这种情况下这不是一个骗局删除,而且速度很慢。 即,如果我将整个属性作为一个对象传递,并在集合端直接调用休眠会话时为每个循环执行一个循环,那么它就可以工作。
session.delete(attribute);
session.getTransaction().commit();
session.close();
我的问题是我在删除批量方法中做错了什么。我在这里有什么遗漏吗?
【问题讨论】: