【问题标题】:Spring MVC won't display correct database value after updateSpring MVC 更新后不会显示正确的数据库值
【发布时间】:2016-02-12 02:33:49
【问题描述】:

在我的控制器中,将 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's 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 不能显示正确的值?

我希望它在刷新时更新

编辑:我已禁用缓存并清除缓存仍有问题。有什么帮助吗?

【问题讨论】:

  • 抱歉,不太清楚你说的 jsp reloaded 是什么意思
  • 数据库前面的应用程序中是否有任何应用程序级缓存或二级缓存?
  • @MadhusudanaReddySunnapu 我不完全确定
  • 如果您的应用中有任何缓存,这可能是您看不到更新值的原因。你可能想检查一下。
  • 我不确定缓存是否是问题所在。我的意思是它可能是,但我清除了缓存并设置了标题,它仍然没有显示正确的值。

标签: java spring spring-mvc


【解决方案1】:

绝对PersistenceContextType.EXTENDED 范围是您确定的问题的根本原因。原因如下:

PersistenceContextType.TRANSACTION 范围内,Spring 框架负责管理注入的entitymanager 的生命周期。 TRANSACTION 作用域的生命周期与底层 transaction 相关联,并且在事务提交/回滚时,entityManager 被 Spring 框架关闭。

但是对于PersistenceContextType.EXTENDED 范围,Spring 框架只负责注入entitymanagerEXTENDED 范围实体管理器的生命周期与用户 transaction 无关,它可以跨越多个事务。完成后由应用程序/用户明确关闭entityManager。如果不是,它将永远保持打开状态(或直到 Spring 容器关闭)。

我假设在您的 userDAO 中您没有明确关闭 entityManager。 'userDAO' 也可能是单例。因此,仅注入一次的同一 entityManager 在多个调用(或 http 请求)中使用

有了这个entityManager' remains open forever and so when you try to access any object (User/Plugin/UserDetails) theentityManager`检查它的第一级缓存,它将检查它在其中找到的第一级缓存(第一次加载)并从它的第一级缓存返回这个对象(这是stale) 而不是访问数据库获取数据。

显然,对于TRANSACTION 范围,只要事务完成(或方法退出),Spring 框架就会关闭entityManager。这导致为每个请求(在您的情况下是 Web 请求)创建一个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;

它有效。感谢那些评论并试图提供帮助的人/

编辑:我讨厌回答我自己的问题,所以如果有人可以深入解释为什么会这样,我会接受它作为答案。

【讨论】:

    【解决方案3】:

    http://docs.oracle.com/javaee/6/tutorial/doc/gkjio.html

    禁用 JPA 二级缓存,否则实体管理器无法识别直接在数据库中更改的更改数据 放

    @Cacheable(false)
    

    到你的实体

    【讨论】:

    • 我已经说过解决方案是什么,我还说禁用任何缓存都不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多