Почему составной объект гибернации не завершен после сохранения? - PullRequest
0 голосов
/ 04 мая 2018

Я поддерживаю устаревшее приложение 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-запросе все данные согласованы.

Я имею в виду два решения, и мне не нравятся оба, потому что они просто обходные пути:

  • явно загружать составные поля (по коду) после persist ()

  • совершать и начинать новую транзакцию после каждого persist ()

Есть идеи, почему у меня такое поведение? Есть идеи для хорошего решения?

Заранее спасибо!

...