Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC won't display correct database value after update

In my controller, put a value from a MySQL database into a ModelAndView object

There is a separate program that updates the table and the MVC is supposed to grab that value so there are no forms to update that table.

When the table is updated, and when I hit refresh on the browser, the values will not update on the page.

Controller

@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;
}

I know this is pretty looked down upon, but I putting that value in Javascript.

like this:

<c:set var="json" value="${json}"/> 

var __data__ = ${json};

Why won't the MVC display the correct value when the database is updated?

I want it to update on refresh

EDIT: I've disabled caching and cleared cache still have a problem. Any help?

like image 661
bmarkham Avatar asked Feb 12 '16 02:02

bmarkham


People also ask

Why does Spring MVC have 404 error?

In this quick article, we explained how to debug 404 errors in Spring MVC. We went through the two most common reasons for receiving a 404 response from our Spring application. The first was using an incorrect URI while making the request. The second was mapping the DispatcherServlet to the wrong url-pattern in web.

What is true about @RequestMapping annotation in Spring MVC?

The @RequestMapping annotation can be applied to class-level and/or method-level in a controller. The class-level annotation maps a specific request path or pattern onto a controller. You can then apply additional method-level annotations to make mappings more specific to handler methods.

Is Spring MVC still used?

Is Spring MVC still used? Yes. Whenever someone uses Spring Boot for creating RESTful web services, chances are they are using Spring MVC (part of Spring Web starter, see http://start.spring.io and search Web in dependencies) although Spring has also been offering another web framework, Spring WebFlux.

What does the most common controller configuration return to locate the view?

The controller returns an object of ModelAndView. The DispatcherServlet checks the entry of view resolver in the XML file and invokes the specified view component.


2 Answers

Definitely PersistenceContextType.EXTENDED scope is the root cause for your problem as you identified. The reason below:

With PersistenceContextType.TRANSACTION scope, Spring framework takes responsibility of managing the life cycle of the injected the entitymanager. The life of TRANSACTION scope is tied to the underlying transaction and upon commit/rollback of the transaction the entityManager is closed by the spring framework.

But with PersistenceContextType.EXTENDED scope, Spring framework takes responsibility of only injecting the entitymanager. The life cycle of EXTENDED scoped entity manager is not tied to the user transaction and it can span multiple transactions. It is up to the application/user to explicitly close the entityManager once we are done with it. If not it will remain open forever (or till Spring container is closed).

I presume in your userDAO you are not closing entityManager explicitly. And also 'userDAO' could be a singleton. So the same entityManager that got injected only once is being used across multiple calls (or http requests)

With this the entityManager' remains open forever and so when you try to access any object (User/Plugin/UserDetails) theentityManager` checks its first level cache, it will check its first level cache which it finds in it (that got loaded for the first time) and returns this object form its first level cache (which is stale) instead of hitting the database for the data.

And obviously with TRANSACTION scope the entityManager is closed by the Spring framework whenever transaction is completed (or method exits). This results in creating an entityManager for each request (in your case web request) hits the the database which has the updated data.

See if this link helps. http://forum.spring.io/forum/other-spring-related/ejb/18445-injection-of-persistencecontext-with-persistencecontexttype-extended

like image 197
Madhusudana Reddy Sunnapu Avatar answered Nov 04 '22 12:11

Madhusudana Reddy Sunnapu


So the solution I have has nothing to do with the code I posted, but in my UserDAO.java class.

Simple change.

From this:

@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;

To this:

@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager em;

and it works. Thank for the people who commented and tried to help/

EDIT: I hate answering my own questions, so if someone could have an in depth explanation on why this works, I'll accept it as an answer.

like image 24
bmarkham Avatar answered Nov 04 '22 12:11

bmarkham