2016-02-12 9 views
11

Nel mio controller, mettere un valore da un database in un MySQLModelAndView objectSpring MVC non visualizzerà il valore di database corretto dopo l'aggiornamento

C'è un programma separato che aggiorna la tabella e il MVC si suppone per afferrare quel valore quindi non ci sono moduli per aggiornare quella tabella.

Quando la tabella viene aggiornata , e quando ho colpito di aggiornamento del browser, i valori non aggiornare sulla pagina.

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

So che questo è praticamente guardato dall'alto in basso, ma mettendo quel valore in Javascript.

come questo:

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

var __data__ = ${json}; 

Perché non sarà l'MVC visualizzare il valore corretto quando il database viene aggiornato?

voglio per aggiornare il rinfresco

EDIT: Ho la cache disabilitata e cancellato la cache hanno ancora un problema. Qualsiasi aiuto?

+0

Mi dispiace, non sei sicuro di cosa intendi con jsp reloaded – bmarkham

+0

C'è qualche cache a livello di applicazione o cache di secondo livello nella tua app di fronte al database? –

+0

@MadhusudanaReddySunnapu Non sono del tutto sicuro che – bmarkham

risposta

9

Definitivamente lo scope PersistenceContextType.EXTENDED è la causa principale del problema identificato. Il motivo sottostante:

Con lo scopo PersistenceContextType.TRANSACTION, Spring Framework si assume la responsabilità di gestire il ciclo di vita dell'iniezione del entitymanager. La durata dell'ambito TRANSACTION è legata allo transaction sottostante e al momento del commit/rollback della transazione lo entityManager viene chiuso dal framework Spring.

Ma con lo scope PersistenceContextType.EXTENDED, la struttura Spring si assume la responsabilità di iniettare solo lo entitymanager. Il ciclo di vita del gestore entità con scope EXTENDED non è legato all'utente transaction e può estendersi su più transazioni. Spetta all'applicazione/utente chiudere esplicitamente lo entityManager una volta terminato. Altrimenti rimarrà aperto per sempre (o fino a quando il contenitore Spring non sarà chiuso).

Presumo nel userDAO non si sta chiudendo entityManager esplicitamente. E anche 'userDAO' potrebbe essere un singleton. Così lo stesso entityManager che ha ottenuto iniettato una sola volta viene utilizzato su più chiamate (o le richieste HTTP)

Con questo il entityManager' remains open forever and so when you try to access any object (User/Plugin/UserDetails) the entityManager` controlla la sua prima cache livello, controllerà la sua prima cache livello che si trova in esso (che è stato caricato per la prima volta) e restituisce questo oggetto dalla sua cache di primo livello (che è obsoleta) invece di colpire il database per i dati.

E ovviamente con lo scope TRANSACTION lo entityManager viene chiuso dal framework Spring ogni volta che la transazione viene completata (o il metodo termina). Ciò si traduce nella creazione di uno entityManager per ogni richiesta (nel caso in cui la richiesta Web) colpisce il database che contiene i dati aggiornati.

Vedere se questo collegamento è utile. http://forum.spring.io/forum/other-spring-related/ejb/18445-injection-of-persistencecontext-with-persistencecontexttype-extended

+0

Oh, questa è roba eccezionale. Grazie. – bmarkham

4

Quindi la soluzione che ho non ha nulla a che fare con il codice che ho postato, ma nella mia classe UserDAO.java.

Cambiamento semplice.

Da questo:

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

A tal:

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

e funziona. Grazie per le persone che hanno commentato e cercato di aiutare/

EDIT: Odio rispondere alle mie stesse domande, quindi se qualcuno potrebbe avere una spiegazione approfondita sul perché questo funziona, lo accetterò come risposta.

2

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

Disabilitare la cache JPA secondo livello altrimenti il ​​manager entità non rileva dati modificati che è stato cambiato direttamente nel database Mettere

@Cacheable(false) 

sul vostro soggetto

+0

Ho già detto quale soluzione e ho anche detto che disabilitare la cache non ha funzionato. – bmarkham