org.hibernate.hql.internal.QueryExecutionRequestException: не поддерживается для операций DML без использования hibernate - PullRequest
0 голосов
/ 02 декабря 2018

У меня есть приложение весенней загрузки, основанное на 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();

Мой вопрос заключается в том, что я делаю неправильно в методе массового удаления.Есть ли что-то, что я здесь скучаю?

1 Ответ

0 голосов
/ 03 декабря 2018

Это не имеет ничего общего с Modifying.Modifying - это аннотация Spring Data, но вы, похоже, не используете Spring Data.

Вы выполняете query.list(), который используется для выполнения операторов выбора, возвращающих результат.

Поскольку вы пытаетесь выполнить удаление, вам нужно использовать executeUpdate()

, для которого в JavaDoc указано:

Выполните оператор обновления или удаления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...