我有一个数据库,其中用户和地址数据存储在单独的表中。当用户登录我的页面时,我想向他显示一个表单,用户可以通过该表单更改其用户/帐户数据。但是,我最终得到一个例外:org.hibernate.LazyInitializationException: could not initialize proxy - no Session
。无法加载地址属性。用户加载很好,这是我不明白的。我的AddressDAOImpl
看起来像这样:
@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);
}
我的控制器执行此操作:
@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);
}
为什么这不起作用?为什么它对用户数据起作用?
答案 0 :(得分:2)
我假设您的AddressService创建了用于加载地址代理的事务(它是代理,因为您使用了load()而不是get())。从AddressService返回地址时,将关闭与此事务关联的会话。
当您的视图解析程序尝试访问Address代理的属性时,没有可用于运行数据库查询以获取属性的会话。因此例外。
使用get()而不是load(),或者在仍处于事务范围内时访问属性。
答案 1 :(得分:0)
load方法不从数据库中获取地址。它将代理返回到未初始化的地址,假设数据库中存在该地址。使用Session.get
获取地址。
答案 2 :(得分:0)
我认为可能是因为你没有初始化你的sessionfactory配置。尝试使用此类来帮助您创建会话工厂。
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure()
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
希望这会有所帮助
答案 3 :(得分:0)
您可以考虑使用OpenSessionInView模式,即使它并不总是最佳解决方案