Jpa запрос вытягивает из кеша вместо базы данных? - PullRequest
2 голосов
/ 04 декабря 2009

У меня возникла проблема с моими Jpa-запросами, поддерживаемыми Hibernate, возвращающими данные, которые не были обновлены. Я предполагаю, что это проблема с извлечением данных из кэша, а не из самой базы данных.

Например, я изменю и сохраню объект на одной странице, а затем вернусь на предыдущую страницу, где перечислены строки базы данных, и на ней будут показаны объекты, существовавшие до изменения. Я вижу, как мой запрос запускается из моего DAO в моих журналах, и я могу зайти в базу данных и убедиться, что изменения сохранились, но JPA не обновляет данные из базы данных, когда я перехожу на следующую страницу.

Я полагаю, что на работе может быть какое-то кэширование сеансов, поскольку я не увижу обновленное представление базы данных при загрузке страницы в другом веб-браузере.

Как мне исправить эту проблему?

РЕДАКТИРОВАТЬ: Я провел некоторое последующее тестирование, включая регистрацию на моем контроллере, чтобы убедиться, что моя среда MVC (Spring MVC) ничего не кэширует. Нет, даже на уровне контроллера он видит устаревшую информацию базы данных.


Вот фрагмент сопоставления из моего файла сущности ORM;

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = true)
@Column(name = "ID", nullable = false)
private Integer id;
@Basic(optional = false)
@Column(name = "Name", nullable = false, length = 100)
private String name;
@Basic(optional = false)
@Column(name = "DayOffset", nullable = false)
private int dayOffset;
@Basic(optional = false)
@Column(name = "StartTime", nullable = false, length = 5)
private String startTime;
@Basic(optional = false)
@Column(name = "Enabled", nullable = false)
private boolean enabled;
@Basic(optional = false)
@Column(name = "LastTouched", insertable = false, updatable = false, nullable =
false)
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;
@Column(name = "TouchedBy", length = 50)
private String touchedBy;
@JoinTable(name = "ReconciliationSearchRule",
joinColumns = {@JoinColumn(name = "ReconciliationId",
    referencedColumnName = "ID", nullable = false)},
inverseJoinColumns = {@JoinColumn(name = "SearchRuleId",
    referencedColumnName = "ID", nullable = false)})
@ManyToMany(fetch = FetchType.LAZY)
private Collection<SearchRule> searchRuleCollection;
@JoinColumn(name = "ServerId", referencedColumnName = "ID", nullable = false)
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private Server server;
@OneToMany(mappedBy = "reconciliation")
private Collection<Report> reportCollection;

Ответы [ 3 ]

3 голосов
/ 07 декабря 2009

Я понял, что происходит. Мой DAO внедряется как прототип (он же non-singleton), поэтому поддерживающий EntityManager создавался для каждого использования DAO. Изменения базы данных, внешние по отношению к EntityManager, не регистрируются запросами к этому конкретному EntityManager.

Конечно, установка DAO на одноэлементный вызывает другие проблемы с многопоточной частью моего приложения, но это совсем другая проблема.

0 голосов
/ 05 декабря 2009

Например, я изменю и сохраню объект на одной странице, а затем вернусь на предыдущую страницу, где перечислены строки базы данных, и на ней будут показаны объекты, существовавшие до изменения.

Управление кэшем второго уровня должно быть прозрачным, вам не нужно evict() объект вручную после любого обновления, кэш 2-го уровня становится недействительным для целевой таблицы "автоматически" Hibernate.

Итак, мой вопрос: что вы подразумеваете под «возвращением на предыдущую страницу» ? Вы имеете ввиду использование навигатора кнопки «Назад»? Вы перезагрузили страницу? Вы можете уточнить это?

Кроме того, вы можете опубликовать свой файл сопоставления или аннотированный объект?

0 голосов
/ 04 декабря 2009

Есть несколько способов сделать это:

  1. Установите стратегию выселения с помощью @DataCache(timeout = 1000) для рассматриваемой сущности и установите для нее что-то разумное для типа объекта, который вы используете.
  2. Позвоните evict(...) по вашей сущности или классу. Детали реализации этого зависят от того, какого провайдера (например, Hibernate) вы используете.
...