Spring MVC не будет отображать правильное значение базы данных после обновления
В моем контроллере поместите значение из базы данных MySQL
в ModelAndView object
Существует отдельная программа, которая обновляет таблицу, и MVC должна захватить это значение, чтобы не было форм для обновления этой таблицы.
Когда таблица обновляется, а когда я удаляю обновление в браузере, значения не будут обновляться на странице.
контроллер
@SuppressWarnings("unchecked")
@Secured({ "ROLE_USER", "ROLE_ADMIN" })
@RequestMapping(value = { "/", "/welcome" }, method = RequestMethod.GET)
public ModelAndView defaultPage(@ModelAttribute("user") User user) {
Collection<SimpleGrantedAuthority> authorities = (Collection<SimpleGrantedAuthority>) SecurityContextHolder
.getContext().getAuthentication().getAuthorities();
ModelAndView view = new ModelAndView("/hello");
// Redirects to admin page if user has admin role
if (authorities.toString().contains("ROLE_ADMIN")) {
return new ModelAndView("redirect:/admin");
}
/////
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String userName = auth.getName();
User userInfo = userDAO.getUserInfo(userName);
System.out.println("Here the thing " + userInfo.getLastname() + " " + userInfo.getUserDetails());
Details details = userDAO.getDetailsInfo(userInfo.getUserDetails().getLastname(),
userInfo.getUserDetails().getPostcode());
Plugs plugs = userDAO.getPlugInfo(details.getMacAddress());
String json = plugs.getJson();
JSONObject obj = new JSONObject(json); //this is the value that is not updating
String name = obj.getJSONObject("meta").getJSONObject("locate").getString("value");
System.out.println(name);
view.addObject("json", obj);
return view;
}
Я знаю, что это довольно оскорбительно, но я помещаю это значение в Javascript.
вот так:
<c:set var="json" value="${json}"/>
var __data__ = ${json};
Почему MVC не отображает правильное значение при обновлении базы данных?
Я хочу, чтобы он обновлялся при обновлении
EDIT: я отключил кеширование и очищенный кеш, все еще есть проблема. Любая помощь?
Ответы
Ответ 1
Определенно PersistenceContextType.EXTENDED
область является основной причиной вашей проблемы, как вы определили. Причина ниже:
С областью PersistenceContextType.TRANSACTION
структура Spring берет на себя ответственность за управление жизненным циклом введенного entitymanager
. Срок действия области TRANSACTION
привязан к базовому TRANSACTION
, а при фиксации/откате транзакции entitymanager
закрывается каркасом Spring.
Но с областью PersistenceContextType.EXTENDED
инфраструктура Spring берет на себя ответственность за ввод только entitymanager
. Жизненный цикл диспетчера объектов EXTENDED
не привязан к пользователю TRANSACTION
и может охватывать несколько транзакций. Является ли приложение/пользователь явно закрывать entitymanager
, как только мы с ним закончим. Если он не останется открытым навсегда (или до закрытия контейнера Spring).
Я предполагаю, что в userDAO
вы не закрываете entitymanager
явно. А также "userDAO" может быть синглом. Таким образом, тот же самый entitymanager
, который вводился только один раз, используется для нескольких вызовов (или http-запросов)
При этом entityManager' remains open forever and so when you try to access any object (User/Plugin/UserDetails) the
entityManager` проверяет свой кеш первого уровня, он проверяет свой кеш первого уровня, который он находит в нем (который загружен в первый раз), и возвращает этот объект из своего кеша первого уровня (который устаревший) вместо того, чтобы удалять базу данных для данных.
И, очевидно, с областью TRANSACTION
entitymanager
закрывается структурой Spring всякий раз, когда транзакция завершается (или выходит метод). Это приводит к созданию entitymanager
для каждого запроса (в вашем случае веб-запроса) попадает в базу данных с обновленными данными.
Посмотрите, помогает ли эта ссылка. http://forum.spring.io/forum/other-spring-related/ejb/18445-injection-of-persistencecontext-with-persistencecontexttype-extended
Ответ 2
Итак, решение, которое у меня есть, не имеет ничего общего с кодом, который я опубликовал, но в моем классе UserDAO.java.
Простое изменение.
Из этого:
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
Для этого:
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager em;
и он работает. Спасибо за людей, которые прокомментировали и попытались помочь /
EDIT: Мне не нравится отвечать на мои собственные вопросы, поэтому, если кто-то может получить подробное объяснение, почему это работает, я приму это как ответ.
Ответ 3
http://docs.oracle.com/javaee/6/tutorial/doc/gkjio.html
Отключить кеш второго уровня JPA, иначе менеджер объектов не распознает измененные данные, которые были изменены непосредственно в базе данных
Помещенный
@Cacheable(false)
на ваш объект