Подтвердить что ты не робот

Транзакционная экономия без вызова метода обновления

У меня есть метод, аннотированный с @Transactional. Я извлекаю объект из своей базы данных Oracle, меняю поле и возвращаюсь из метода. Я забыл сохранить объект, но обнаружил, что база данных все равно обновляется.

ApplicationContext

<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

мой метод

@Transactional
public void myMethod(long id) {
    MyObject myObj = dao.getMstAttributeById(id);
    myObj.setName("new name");
    //dao.update(myObj);
}

Мой вопрос: почему MyObject сохраняется в базе данных?

4b9b3361

Ответ 1

Поскольку спящий режим будет автоматически обнаруживать изменения, внесенные в постоянные объекты, и соответственно обновлять базу данных. Это поведение описано в главе 11 справочного руководства по спячке. Соответствующая часть гласит:

Hibernate определяет и поддерживает следующие состояния объектов:

  • Transient - объект является переходным, если он только что был создан с использованием нового оператора и не связан с сеансом Hibernate. Он не имеет постоянного представления в базе данных и не присвоено значение идентификатора. Временные экземпляры будут уничтожены сборщиком мусора, если приложение больше не содержит ссылку. Используйте сеанс Hibernate, чтобы сделать объект постоянным (и пусть Hibernate позаботится о операторах SQL, которые должны быть выполнены для этого перехода).

  • Persistent - постоянный экземпляр имеет представление в базе данных и значение идентификатора. Это может быть просто сохранено или загружено, однако оно по определению входит в сферу сеанса. Hibernate будет обнаруживать любые изменения, сделанные для объекта в постоянном состоянии, и синхронизировать состояние с базой данных, когда блок работы завершается. Разработчики не выполняют инструкции вручную UPDATE или DELETE, когда объект должен быть временным.

  • Отдельно - отдельный экземпляр - это объект, который был постоянным, но его сеанс закрыт. Ссылка на объект по-прежнему действительна, конечно, и отдельный элемент может быть даже изменен в этом состоянии. Отключенный экземпляр может быть повторно подключен к новому сеансу в более поздний момент времени, делая его (и все изменения) постоянным снова. Эта функция позволяет использовать модель программирования для длительных рабочих единиц, для которых требуется время мышления пользователя. Мы называем их транзакциями приложений, т.е. Единицей работы с точки зрения пользователя.

Ответ 2

Если вы используете JPA, в спецификации указано, что если ваше Entity находится в состоянии (и это то, что вы делаете, извлекая данные из DAO в рамках активной транзакции) все внесенные в него изменения будут отражены в базе данных во время транзакции транзакции.

Итак, другими словами - на самом деле не имеет значения, если вы вызываете операцию обновления или нет, потому что фиксация транзакции приведет к сбросу изменений в базу данных.

Ответ 3

Я обнаружил, что предотвращение автоматического обновления базы данных - это двухэтапный процесс.

Шаг I::

getSession().setFlushMode(FlushMode.MANUAL) // [FlushMode.NEVER is depracated in 4.x]

Шаг II:

getSession().clear(); //This will actually discard all changes