Как лучше избежать исключения LazyInitializationException? - PullRequest
1 голос
/ 23 июня 2011

В настоящее время у меня есть дочерняя сущность, которая имеет @ManyToOne связь с родительской сущностью.Предыдущие разработчики установили это поле как lazy="false", чтобы получать родительский элемент при необходимости, когда сеанс также закрыт, однако я решил, что это должно быть lazy="true", поскольку оно используется не всегда, но при этом я столкнулся с LazyInitializationException, потому что сеансзакрывается, и дочерний процесс отсоединяется от сеанса, когда он пытается получить родителя.

Мне было интересно, правильно ли перенести еще немного логики метода run, как показано ниже, в класс обслуживания, который взаимодействуетс DAO s, таким образом, я мог бы избежать исключения, потому что в настоящее время классы обслуживания похожи на простые классы, в которые вставлены необходимые DAO s, и они просто вызывают метод DAO и возвращают результат.Должен ли я добавить как можно больше методов в класс обслуживания, которые взаимодействуют с сущностями, которые бы заполучили пользователя и проверили все на наличие действий при входе в систему, в случае необходимости получили бы родителя, а затем просто вернули результат регистрации в метод run.

public class Login extends Runnable {
     private UserService userService;
     ...
     public void run() {
         ...
         User user = userSerivce.getById(id);
         Account account = user.getAccount(); //LazyInitializationException
         ...
         if (account.isLocked()) {
             ...
         }
         ...
         userService.save(user);

         //Send some message to the user..
     }
}

public class UserServiceImpl implements UserService {
    private UserDAO userDAO;
    ...
    public User getById(long id) {
        return userDAO.getById(id);
    }
    public void save(User user) {
        userDAO.save(user);
    }
}

public UserDAOImpl implements UserDAO {
    private SessionFactory factory;
    ...
    public User getById(long id) {
        return (User) factory.getCurrentSession().load(User.class, id);
    }
    public void save(User user) {
        factory.getCurrentSession().saveOrUpdate(user);
    }
}

Я использую <tx:advice> Spring для обработки закрытия и других связанных с транзакциями вещей.

Ответы [ 2 ]

3 голосов
/ 23 июня 2011

Я предпочитаю, чтобы все мои отношения сущностей были ленивыми, поскольку я не знаю, понадобятся ли мне эти внешние сущности и когда.Таким образом, я могу избежать ненужных объединений, когда мне не нужны дополнительные объекты.Если мне в конце концов понадобится сущность, я создаю именованный запрос и жду извлечения сущности или коллекции.Вот пример .

Я согласен с тем, что вы должны отправлять DTO вместо объекта обратно в ваше приложение вызывающего интерфейса.Спящие сущности полны прокси, и было бы неэффективно отправлять их обратно.Я не совсем уверен, отправляете ли вы эти объекты в файл jsp / speed / etc или во внешнее приложение, но я бы рекомендовал использовать DTO, если вы отправляете обратно JSON или что-то похожее на вызывающее приложение.Вот еще один вопрос, касающийся DTO * , нажмите здесь , где обсуждаются 2 фреймворка для простого преобразования.

0 голосов
/ 23 июня 2011

Создавайте DTO, не отправляйте JPA-сущности по сети.

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

...