У меня есть приложение весенней загрузки, основанное на 2.1.0.RELEASE и использующее hibernate 5.3.7.Final для большинства взаимодействий с базой данных, за исключением пары случаев, когда я хотел удалить список объектов и, таким образом, хотелвыполнить метод, который удаляет этот список как массив.Я уже могу выполнить getBulk как список с обычным hql-запросом, поэтому я хотел сделать то же самое для удаления, так как это намного быстрее.
Объекты создаются следующим образом:
Iиметь атрибут таблицы, который имеет однозначное сопоставление с таблицей с именем 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 в моем классе обслуживания, которая также вызывает delete.
@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
аннотация.Мне пришлось добавить дополнительную зависимость, то есть artifacat spring-data-jpa, так как у меня не было аннотации Modifying.то есть
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
Ну, у меня есть это сейчас, но все равно не позволяет запрос на удаление.
Если я немного изменяю код и использую hibernate для удаления строк, то все это работает, но в данном случае это не полное удаление, и оно медленное.То есть, если я передам весь атрибут как объект и сделаю для каждого цикла сеанс гибернации конца вызова коллекции, то это сработает.
session.delete(attribute);
session.getTransaction().commit();
session.close();
Мой вопрос заключается в том, что я делаю неправильно в методе массового удаления.Есть ли что-то, что я здесь скучаю?