Hibernate - как получить список затронутых идентификаторов после обновления запроса - PullRequest
0 голосов
/ 09 июля 2020

Я проверил это решение, но оно не сработало в моем случае - { ссылка }

Я работаю с Mysql.

Если я сделаю следующее -

Session session = em.unwrap(Session.class);
    
    Query query = em.createNativeQuery("UPDATE Table tr SET tr.status=:newStatus WHERE tr.status=:oldStatus and tr.processAfter<now()");
    query.setParameter("newStatus", 0);
    query.setParameter("oldStatus",1);
    query.executeUpdate();
List<Table> empList = query.list();  //I get undefined method error - Error:(513, 57) java: cannot find symbol symbol:   method list()  location: variable query of type javax.persistence.Query


    List<Table> empList = query.getResultList(); //can't do this on dml case

Я получаю это исключение с getResultList () -

2020-07-09 21:53:46:850 [Thread-10][] DEBUG org.hibernate.engine.jdbc.spi.SqlExceptionHelper[line:124] [] - could not extract ResultSet [n/a]
java.sql.SQLException: Can not issue data manipulation statements with executeQuery().
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:965) ~[mysql-connector-java-5.1.45.jar:5.1.45]
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:898) ~[mysql-connector-java-5.1.45.jar:5.1.45]
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:887) ~[mysql-connector-java-5.1.45.jar:5.1.45]
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:861) ~[mysql-connector-java-5.1.45.jar:5.1.45]
        at com.mysql.jdbc.StatementImpl.checkForDml(StatementImpl.java:469) ~[mysql-connector-java-5.1.45.jar:5.1.45]
        at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1923) ~[mysql-connector-java-5.1.45.jar:5.1.45]
        at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-2.7.8.jar:?]
        at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-2.7.8.jar:?]
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.loader.Loader.getResultSet(Loader.java:2168) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1931) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1893) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.loader.Loader.doQuery(Loader.java:938) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.loader.Loader.doList(Loader.java:2692) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.loader.Loader.doList(Loader.java:2675) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.loader.Loader.list(Loader.java:2502) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:335) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2161) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1016) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:152) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at org.hibernate.query.Query.getResultList(Query.java:146) [hibernate-core-5.2.14.Final.jar:5.2.14.Final]
        at com.project.service.Service.Method(Service.java:514) [classes/:?]
        

1 Ответ

0 голосов
/ 10 июля 2020

Если вы работали с базой данных, которая поддерживает это, вы могли бы использовать Blaze-Persistence, библиотеку, которая работает поверх JPA / Hibernate, что добавляет поддержку для этого.

Вот дополнительная информация об этом : https://persistence.blazebit.com/documentation/core/manual/en_US/index.html#returning -from-update-statement

Поскольку вы используете MySQL, я думаю, что лучший способ сделать это следующий:

  1. Создайте запрос SELECT, который извлекает идентификаторы затронутого объекта и использует pessimisti c блокировку
  2. Выполняйте обновления на основе идентификаторов
  3. (необязательно) Получите любые данные, которые вам нужны, на основе the ids

К сожалению, это лучшее, что можно сделать с помощью MySQL. В какой-то момент Blaze-Persistence добавит эмуляцию, реализующую эту схему, поэтому вам не нужно думать о том, как это сделать, но, тем не менее, модель производительности будет отличаться от той, которую вы ожидали.

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