Здесь я в замешательстве, и, возможно, это что-то очевидное, потому что мой опыт в Hibernate слабее, чем в других областях.
В унаследованном коде есть класс Hibernate @Entity
Foo
. Одно из его свойств:
private OldBar bar = new OldBar();
OldBar
— это класс @Embeddable
, который использует один столбец, foobar
:
@Embeddable
public class OldBar {
private String fooBar;
@Column(length = 10, nullable = false)
private String getFooBar() {
return fooBar;
}
@SuppressWarnings("unused")
private void setFooBar(String fooBar) {
this.fooBar = fooBar;
}
}
Исходная проблема в том, что мне нужно было чтобы что-то сделать с OldBar.fooBar
, но первоначальный дизайн имел ограничения и имел это поле закрытым, что не позволяло мне создать его подкласс, поэтому мне пришлось создать совершенно другой класс, NewBar
, чтобы заменить другой и получить доступ к приватному полю. Я подумал, что поскольку NewBar
также является Embeddable
и имеет такое же обозначение @Column
, я мог бы просто поменять местами поле в классе Foo
:
private NewBar bar = new NewBar();
Я хотел сделать это, потому что у меня есть данные в столбце foobar
, и я хотел прозрачно использовать эти данные с NewBar
вместо OldBar
. ].
Из журналов трассировки я увидел, что Foo()
создается с версией по умолчанию NewBar()
, как и следовало ожидать, при вызове конструктора. Однако к моменту вызова кода Foo.getBar()
, по какой-то причине bar
равно null
! Я предполагаю, что Hibernate по какой-то причине устанавливает для него значение null
, но почему Hibernate не читает данные из столбца foobar
и не создает экземпляр NewBar
? Почему он снова начинает работать, когда я возвращаю OldBar
вместо NewBar
? Наверняка в самой базе данных нет ничего, что говорило бы о том, какой из классов @Embeddable
сопоставлен со столбцом, не так ли?
Обновление:Это становится все более и более странным. Иногда я оставляю код на ночь, и на следующий день он работает! Или на следующий день не работает! Только сейчас это не сработало (то есть свойство foobar
было установлено в null
вместо значения в базе данных), поэтому я сделал класс ExactCopyOfOfOldBar
и поместите его вместо OldBar
. Он работал нормально! Поэтому я снова переключаюсь на NewBar
--- просто отменяя свои временные изменения. Это все еще работало, чего раньше не было! Есть ли какой-то кеш, в котором Hibernate сериализует значения и не получает их из базы данных? Это очень странно.
Обновление: Теперь я больше не могу заставить NewBar
работать вообще. Я создаю OtherBar
, который в основном идентичен NewBar
за исключением того, что у него другое имя, и я подключаю его, и он работает, правильно читая встроенную строку. Я снова переключаюсь на NewBar
и снова получаю null
. Что здесь происходит?
Обратите внимание, что Foo
загружается через net.databinder.auth.hib.AuthDataApplication.getUser(String username)
, что достаточно просто:
return (DataUser) Databinder.getHibernateSession().createCriteria(getUserClass())
.add(Restrictions.eq("username", username)).uniqueResult();
Я снова и снова проверял, что таблица Foo
(user) имеет одну строку с правильные данные, и самое главное, что в поле foobar
есть данные. Почему Hibernate возвращает мне Foo
с полем null
foobar
? Почему простое переключение с NewBar
на OtherBar
заставляет его снова работать? Почему он работает весь день, а затем перестает работать после того, как я оставил его на ночь?