Я использую Spring 3, Hibernate 3.3.1 и MySQL 5.1.x (на Red Hat 5, также наблюдайте то же поведение, когда на Windows, однако). Я замечаю, что строка в базе данных обновляется, но одна из ссылок на объекты в памяти не обновляется. Я постараюсь описать структуру класса в упрощенной форме ..
class A {
@OneToMany(cascade = CascadeType.ALL)
List<Widget> widgets;
@OneToMany(cascade = CascadeType.ALL)
@Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
List<B> bObjects;
@Transactional
public void turnOnWidgets() { ... }
}
class B {
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
@Cascade(value = { org.hibernate.annotations.CascadeType.LOCK, org.hibernate.annotations.CascadeType.EVICT})
private A aObj;
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void turnOnWidgets() {
for (Widget w : aObj.getWidgets()) {
w.setOn(true);
}
}
}
class Widget {
Boolean on;
}
Вот последовательность действий. Когда вызывается A.turnOnWidgets, он перебирает свою коллекцию «bObjects» и вызывает «turnOnWidgets» для каждого объекта B. Объект B изменяет свойство «on» для каждого виджета, на который ссылается объект A (как показано выше в B.turnOnWidgets).
Когда это происходит, я могу посмотреть на базу данных и увидеть, что значение "on" изменилось для виджетов. Однако, когда я захожу в код с помощью отладчика, я замечаю, что объект B ссылается на другой экземпляр A (например, тот же A из базы данных, но в памяти это другой экземпляр объекта Java), чем A, который я вызвал "turnOnWidgets" на.
По сути, я вижу, что когда я перемещаюсь по графу объектов, просматривая виджеты, содержащиеся в экземпляре A, свойство "on" виджетов имеет значение false. Однако, если я посмотрю на виджеты, перейдя от B.aObj.getWidgets()
, их свойство "on" будет истинным.
Когда мое приложение работало с базой данных Oracle, все это работало нормально, как только я переключился на MySQL
, я начал видеть эту проблему.
Кто-нибудь знает, есть ли что-то особенное в MySQL
(возможно, в сочетании с Hibernate и / или Spring)?
UPDATE
Так что я думаю, что я сузил его до раздела в коде, где JPA-обновление выполняется для объекта "B". При работе с oracle это приводит к правильному обновлению объектов в памяти, однако при работе с MySQL объекты не обновляются должным образом. Еще нужно выяснить почему.