Я определил следующий класс как стандартный Entity Listener, поэтому каждый раз, когда я вызываю методы persist() или merge(), этот код будет выполнен автоматически:
public class StringProcessorListener {
@PrePersist
@PreUpdate
public void formatStrings(Object object) {
try {
for (Field f : object.getClass().getDeclaredFields()) {
if (f.getType().equals(String.class)) {
f.setAccessible(true);
if (f.get(object) != null) {
f.set(object, f.get(object).toString().toUpperCase());
}
}
}
} catch (Exception ex) {
Logger.getLogger(StringProcessorListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Целью этого является использование всех строк объекта перед его вставкой в базу данных. @PrePersist работал отлично, метод изменяет все строки и сохраняет его в записях в базе данных, но когда я пытаюсь обновить объект, он не работает так хорошо, метод вызывается нормально, а также изменяет строки, но вместо сохранения измененного объекта в базе данных он сохраняет объект так же, как и до этого метода.
Любые идеи о том, как это решить?
Обновить:
Я решил его с помощью DescriptorEvent
, он дал мне доступ к ObjectChangeSet, и я мог бы его вручную обновить, а затем значения были правильно сохранены в базе данных.
Если вы работаете в среде сервера или используете агент для плетения, EclipseLink по умолчанию будет использовать отслеживание изменений, если это возможно по соображениям производительности. Если это так, ваш метод непосредственного задания значений в объекте обходит сплетенный код замены, поэтому EclipseLink не знает об изменениях. O persist, он использует все значения непосредственно из объекта, в то время как при обновлениях он использует только измененные поля, и он будет знать только об изменениях через слушателей смены изменений. Вам нужно либо использовать доступ к методу для установки этих полей, либо отключить отслеживание изменений: http://eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_changetracking.htm