Hibernate LazyInitializationException - 如何解决此问题?

时间:2011-12-08 16:34:36

标签: java hibernate spring lazy-loading

我有一个数据库,其中用户和地址数据存储在单独的表中。当用户登录我的页面时,我想向他显示一个表单,用户可以通过该表单更改其用户/帐户数据。但是,我最终得到一个例外: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);
}

为什么这不起作用?为什么它对用户数据起作用?

4 个答案:

答案 0 :(得分:2)

我假设您的AddressService创建了用于加载地址代理的事务(它是代理,因为您使用了load()而不是get())。从AddressService返回地址时,将关闭与此事务关联的会话。

当您的视图解析程序尝试访问Address代理的属性时,没有可用于运行数据库查询以获取属性的会话。因此例外。

使用get()而不是load(),或者在仍处于事务范围内时访问属性。

答案 1 :(得分:0)

load方法不从数据库中获取地址。它将代理返回到未初始化的地址,假设数据库中存在该地址。使用Session.get获取地址。

请参阅http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/Session.html#load%28java.lang.Class,%20java.io.Serializable%29

答案 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模式,即使它并不总是最佳解决方案