Spring Transaction пытается запустить обновление после выбора запроса

У меня есть метод DAO, который выполняет простой запрос выбора:

@Transactional
public List<Object[]> getMyTableData(Long someId)
{
    Session session = (Session) getEntityManager().getDelegate();

    return session
        .createSQLQuery("SELECT * FROM my_table where some_id = :someId")
        .addEntity(MyTable.class)
        .setParameter("someId", someId)
        .list();
}

Когда я запускаю его, я нахожу в журналах два запроса:

  1. Запрос "выберите * из MyTable, где some_id =...", который успешно получает результат
  2. И после этого я нахожу это в своих журналах:

    org.springframework.orm.jpa.JpaTransactionManager: инициация фиксации транзакции org.springframework.orm.jpa.JpaTransactionManager: фиксация транзакции JPA в EntityManager [org.hibernate.ejb.EntityManagerImpl@162add4] org.hibernate.transaction.JDBCTransaction: фиксации org. hibernate.event.def.AbstractFlushingEventListener: обработка каскадов времени сброса org.hibernate.event.def.AbstractFlushingEventListener: сброс: 0 вставок, 1 обновление, 0 удалений для 2 объектов

затем он запускает еще один запрос «Обновить набор my_table ....»

Почему этот запрос на обновление выполняется?


person Kevindra    schedule 04.12.2012    source источник
comment
Большая часть этого журнала указывает на то, что ваша транзакция закрывается. Поскольку Transactional находится вокруг метода getMyTableData(), он начнет транзакцию перед методом и закроет ее в конце (если вызывающий метод также не аннотирован Transactional, и в этом случае он просто присоединится к более крупной транзакции). В JPA, когда транзакция фиксируется, JPA записывает любые измененные объекты в базу данных. Странно то, что в показанном вами примере вы вообще не изменили результаты запроса. В вашем реальном приложении вы что-нибудь делаете с возвращаемыми объектами?   -  person Pace    schedule 04.12.2012
comment
Нет, я ничего не обновлял в наборе результатов. Но я понял, что если вы добавите readOnly = true в аннотацию транзакции, это не обновит ваши сущности.   -  person Kevindra    schedule 04.12.2012


Ответы (1)


Как упоминал Пейс выше, «в JPA, когда транзакция фиксируется, JPA записывает любые измененные объекты в базу данных». Поэтому я попытался добавить readOnly = true к аннотации @Transactional, и это решило проблему.

person Kevindra    schedule 04.12.2012
comment
У меня та же проблема, когда я выбираю строку из представления, и я получаю сообщение «Невозможно изменить более одной базовой таблицы из-за ошибки представления соединения», я пытался использовать readOnly=true для @transactional, однако это не сработало. - person Manglesh; 22.06.2017