Hibernate LazyInitializationException - Как мне решить эту проблему? - PullRequest
0 голосов
/ 08 декабря 2011

У меня есть база данных, в которой данные о пользователях и адресах хранятся в отдельных таблицах.Когда пользователь входит на мою страницу, я хочу показать ему форму, с помощью которой он может изменить данные своего пользователя / учетной записи.Тем не менее, я получаю исключение: 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 ]

2 голосов
/ 08 декабря 2011

Я предполагаю, что ваш AddressService создал транзакцию, используемую для загрузки прокси-сервера адресов (это прокси, потому что вы использовали load () вместо get ()). Сеанс, связанный с этой транзакцией, закрывается при возврате адреса из службы AddressService.

К тому времени, когда ваш распознаватель представлений попытается получить доступ к атрибутам прокси-сервера адресов, сеанс недоступен, через который можно выполнить запрос к базе данных для получения атрибутов. Отсюда и исключение.

Либо используйте get () вместо load (), либо обращайтесь к атрибутам, пока вы находитесь в области транзакции.

0 голосов
/ 10 декабря 2011

Вы можете рассмотреть возможность использования шаблона OpenSessionInView, даже если это не всегда лучшее решение

0 голосов
/ 08 декабря 2011

Я думаю, что это возможно, потому что вы не инициализировали свою фактическую конфигурацию сеанса. Попробуйте этот класс, чтобы помочь вам создать фабрику сеансов.

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

}

надеюсь, это поможет

0 голосов
/ 08 декабря 2011

Метод загрузки не выбирает адрес из базы данных.Он возвращает прокси на неинициализированный адрес, предполагая, что адрес существует в базе данных.Используйте Session.get, чтобы получить адрес.

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

...