如何更好地避免LazyInitializationException?

时间:2011-06-23 16:12:32

标签: java business-logic service-layer lazy-initialization

目前我有一个与其父实体有@ManyToOne关联的子实体。以前的开发人员已将此字段设置为lazy="false",以便在会话关闭时随时获取父级,但我认为它应该是lazy="true",因为它并不总是被使用但是在这样做时我遇到了{{} 1}}因为会话已关闭,并且当孩子尝试获取父级时会将其与会话分离。

我想知道是否正确移动LazyInitializationException方法的更多逻辑,如下所示,与run s交互的服务类,因此我可以避免异常,因为目前服务类是像普通类一样,它们注入了所需的DAO,它们只调用DAO方法并返回结果。 我应该在与实体交互的服务类中放置更多方法,这将获取用户并检查登录操作的所有内容,如果需要则获取父级,然后将登录结果返回到DAO方法。

run

我使用Spring的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); } } 来处理结束和其他与交易相关的事情。

2 个答案:

答案 0 :(得分:3)

我更喜欢将我的所有实体关系都视为懒惰,因为我不知道是否以及何时需要这些外部实体。这样,当我不需要其他实体时,我可以避免不必要的连接。如果我最终需要实体,我创建一个命名查询并急切地获取实体或集合。这是一个example

我同意你应该将DTO而不是实体发送回你的主叫前端应用程序。 Hibernate实体充满了代理,发送它们效率很低。我不确定您是将这些对象发送到jsp / velocity / etc文件还是外部应用程序,但如果您要发回JSON或类似于调用应用程序的东西,我建议使用DTO。这是另一个涉及DTO click here的问题,讨论了2个易于转换的框架。

答案 1 :(得分:0)

创建DTO,不要通过网络发送JPA实体。

创建DTO时,您必须访问所需的属性,触发加载它们的内容。