Я поддерживаю устаревшее приложение CRUD с относительно простой моделью данных. Чтобы повысить производительность за счет включения отложенной загрузки, я переключился с сеанса Hibernate на запрос БД (openSession / closeSession, окружающий каждый запрос) на транзакцию Hibernate на HTTP-запрос, выполняемый фильтром Tomcat:
public class HibernateSessionRequestFilter implements Filter {
public void doFilter ... {
HibernateSession.getSessionFactory().getCurrentSession().beginTransaction();
chain.doFilter(request, response);
HibernateSession.getSessionFactory().getCurrentSession().getTransaction().commit();
Что касается чтения данных, все работает нормально.
Но есть проблема, когда составной объект сохраняется и затем отображается в том же запросе (транзакции). Отображение объекта похоже на
<class name="xxx.data.ReportDescription" table="report_descriptions">
...
<many-to-one name="job" class="xxx.data.Job" column="jobId"/>
Постоянный код:
Session session = HibernateSession.currrentSession();
session.persist(reportDescription);
LOGGER.info("report PERSISTED: " + reportDescription.getJob());
Выходные данные LOGGER "job PERSISTED" показывают, что объект Job имеет только действительный идентификатор, а все остальные его поля имеют значения null, что неверно - существующий объект Job, на который указывает новый объект reportDescription, не имеет нулевых значений во всех его поля.
Если я продолжу, загрузив reportDescription заново в рамках той же транзакции, используя:
ReportDescription fetchedReportDescription =
ReportDescriptionHelper.getReportDescription(reportDescription.getId());
LOGGER.info("report FETCHED: " + fetchedReportDescription);
Я снова получаю составной объект Job с действительными значениями id и null в других полях.
Если я закрываю транзакцию и начинаю новую, все работает нормально:
HibernateSession.getSessionFactory().getCurrentSession().getTransaction().commit();
HibernateSession.getSessionFactory().getCurrentSession().beginTransaction();
fetchedReportDescription =
ReportDescriptionHelper.getReportDescription(reportDescription.getId());
LOGGER.info("report FETCHED: " + fetchedReportDescription);
Логически, при следующем HTTP-запросе все данные согласованы.
Я имею в виду два решения, и мне не нравятся оба, потому что они просто обходные пути:
Есть идеи, почему у меня такое поведение? Есть идеи для хорошего решения?
Заранее спасибо!