У меня есть небольшое веб-приложение на основе Spring MVC и Hibernate.Мой пользовательский объект имеет отношение oneToMany с Pet, object:
@OneToMany(mappedBy="user", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Set<Pet> myPets;
Даже я сохраняю свой пользовательский объект в сеансе после входа в систему (я знаю, это грех), и в него включаются его домашние животные, каждый разметод Controller вызывается, после того, как он возвращает объект ModelAndView, в журналах показывается выбор режима гибернации.
Например,
@RequestMapping(value = "/in_pet-see", method = RequestMethod.GET)
public ModelAndView getSee(@RequestParam("pid") Integer pId, ModelAndView model) {
User u = getUserFromSession();
if(u==null) {
u = getUser();
}
Set<Pet> pets = u.getMyPets();
Pet p = getPetFromSet(pets, pId);
model.addObject("user", u);
model.addObject("petType", petTypeMap.get(p.getType()));
model.addObject("petAttribute", p);
model.setViewName("b-see-pet");
return model;
}
private User getUserFromSession() {
return (User)session().getAttribute("user");
}
public static HttpSession session() {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
return attr.getRequest().getSession(true); // true == allow create
}
private Pet getPetFromSet(Set<Pet> set, int pId) {
Pet myPet = null;
for (Iterator<Pet> it = set.iterator(); it.hasNext(); ) {
Pet p = it.next();
if (p.getPetId()==pId) {
myPet = p;
}
System.out.println("Pet found");
}
return myPet;
}
Как этого избежать?
ПРИМЕЧАНИЕ
Мой способ исправить это - клонировать спящий объект и поместить клона.в HttpSession, затем в тех методах, которые могут вносить изменения (редко встречающиеся в моем приложении) в зависимые объекты пользователя или пользователя, в конце этого метода вызывается метод синхронизма:
/** Get a new user from DDBB, after some change and put it on Session to deliver fresh data */
private void sinchronizeUser() {
User oldSmith = getUserFromSession();
User u = myUserService.loadUserById(oldSmith.getUserId());
User smith = (User) u.clone();
session().setAttribute("user", smith);
}