I have a Database where user and address data is stored in separate tables. When a user logs in to my page I want to show him a form with which he can change his user/account data. However, I end up getting an Exception: org.hibernate.LazyInitializationException: could not initialize proxy - no Session. The address attributes can’t be loaded. The user loads just fine and that’s what I don’t understand. My AddressDAOImpl looks like this:
@Autowired
private SessionFactory sessionFactory;
public void addAddress(Address address)
{
sessionFactory.getCurrentSession().save(address);
}
public void updateAddress(Address address)
{
sessionFactory.getCurrentSession().update(address);
}
public List<Address> listAddress()
{
return sessionFactory.getCurrentSession().createQuery("from address").list();
}
public void deleteAddress(int id)
{
Address addr = (Address) sessionFactory.getCurrentSession().load(Address.class, id);
if(addr != null)
{
sessionFactory.getCurrentSession().delete(addr);
}
}
public Address getAddress(int id)
{
return (Address) sessionFactory.getCurrentSession().load(Address.class, id);
}
My Controller does this:
@RequestMapping("/library/home")
public ModelAndView showHome()
{
String username = SecurityContextHolder.getContext().getAuthentication().getName();
User user = userService.getUser(username);
Address address = addressService.getAddress(user.getId());
ModelMap mmap = new ModelMap();
mmap.addAttribute("user", user);
mmap.addAttribute("addresse", address);
return new ModelAndView("/library/home", mmap);
}
Why doesn’t this work? And why does it work for the user data?
I’m assuming that your AddressService created the transaction used to load the Address proxy (it’s a proxy because you used load() instead of get()). The session associated with this transaction is closed when you return the Address from the AddressService.
By the time your view resolver tries to access the attributes of the Address proxy, there is no session available through which a database query can be run to fetch the attributes. Hence the exception.
Either use get() instead of load(), or access the attributes while you’re still in the scope of the transaction.