LazyInitializationException с OneToMany самым простым способом - PullRequest
1 голос
/ 27 сентября 2011

Я использую Hibernate с jpa и получаю LazyInizializationException, пытаясь сделать очень простую вещь. Я знаю, что означает LazyInizializationException, но я не могу понять, почему это происходит, когда я делаю все наиболее распространенным и простым способом. Это одна сторона отношений:

@Entity
public class User implements Serializable{

@Id @GeneratedValue
private int idUser;

private String name;
private String surname;
private String username;

@OneToMany(mappedBy="user")
private List<Device> dev;

...getters and setters...

и это сторона "Множество":

@Entity
public class Device implements Serializable {

@Id @GeneratedValue
private int idDevice;

private String brand;
private String model;

@ManyToOne
@JoinColumn(name="user_fk")
private User user;

...getters and setters...

Тест jUnit, который выдает исключение:

@Test
public void testLazyUserSnd() {
    User u = uDao.getUser(2);
    List<Device> devList = u.getDev();
    Device aDevice = devList.get(0); // <--- Here the exception is thrown
    aDevice.getModel();

Я установил отношения, как описано в Документация Hibernate . Любой намек? Я делаю какие-то большие и глупые ошибки?

Ответы [ 3 ]

3 голосов
/ 27 сентября 2011

Хотя ответ @ Xavi вполне обоснован, вы не всегда можете загружать устройства для пользователя.Если вы этого не сделаете, есть 2 способа исправить это.

  1. Создайте дополнительный метод uDao.getUserWithDevices (id) и вызовите его, когда вы знаете, что вам нужны устройства, в противном случае вызовите uDao.getUser (id).
  2. Инкапсулируйте тестовый метод,и, следовательно, любой производственный код, который использует метод, в транзакции.Другими словами, оставляйте сеанс открытым столько, сколько вам нужно.

Лично я бы использовал метод транзакции, поскольку он обеспечивает большую гибкость и позволяет JPA выполнять отложенную загрузку всякий раз, когда это необходимо.См. Также http://community.jboss.org/wiki/OpenSessionInView для получения более интересной информации о жизненном цикле сеанса.

1 голос
/ 27 сентября 2011

Исключение говорит вам, что вы пытаетесь получить некоторые лениво загруженные элементы ассоциации, когда сессия закрыта. Возможно, вам следует вызвать u.getDev() или Hibernate.initialize(u.getDev()) внутри метода дао, когда сеанс гибернации еще открыт.

Или, если вы используете Criteria, вы также можете использовать setFetchMode для принудительной загрузки.

 public User getUser(String id) {
   Session session = getSession();
   Criteria criteriaQuery = session.createCriteria(User.class);
   criteriaQuery.add(Expression.eq("id", id));
   criteriaQuery.setFetchMode("dev", FetchMode.JOIN);
   return criteriaQuery.uniqueResult();
 }
0 голосов
/ 27 сентября 2011

Сущность, вероятно, отсоединяется от сеанса (контекста транзакции) при доступе к отношению. Попробуйте заключить свой тестовый метод в транзакцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...