我有一些彼此关系的模型类(User
,Group
,Message
等)。由于很多原因(我没有提供详细信息,但这不是一个灵活的决定)关系是懒惰,我希望它们保持懒惰。
有时我想加载一些类集合。体育user.getGroups()
或user.getMessages()
但是,由于延迟加载,我需要在DAO类的方法中调用Hibernate.initialize()
,这对我来说没问题。
问题是,是否有策略避免声明许多DAO方法加载多个集合组合,重用这些方法?
以下是我想避免的内容的示例:
UserController中:
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/user/view/{id}", method = RequestMethod.GET)
public String view(@PathVariable Long id, Model model) {
// Choose one between the following, depending on the case
User user = userService.getUser(id);
User user = userService.getUserWithGroups(id);
User user = userService.getUserWithGroupsAndMessages(id);
//...
}
}
UserDAOImpl :
@Repository
public class UserDAOImpl implements UserDAO {
@Override
public User getUser(long id) {
return (User) this.getCurrentSession().get(User.class, id);
}
@Override
public User getUserWithGroups(long id) {
User user = (User) this.getCurrentSession().get(User.class, id);
Hibernate.initialize(user.getGroups());
return user;
}
@Override
public User getUserWithGroupsAndMessages(long id) {
User user = (User) this.getCurrentSession().get(User.class, id);
Hibernate.initialize(user.getGroups());
Hibernate.initialize(user.getMessages());
return user;
}
}
重点是我想避免为每个案例必须加载的每个集合组合创建多个DAO方法。我希望在Controller中实现类似于User user = userService.getUser(id).initGroups().initMessages();
的调用语法,以便在每种情况下仅链接我需要的特定方法。
但在此特定示例中,initXXX()
方法将位于模型类User
中,该类可能不包含任何@Autowired service
,因此不是可能的解决方案。< / p>
有什么想法吗?
- 编辑 -
一些非工作的想法:
选项1。在initGroups()
模型类中声明User
:
用户
@Entity
@Table(name="user")
public class User implements Serializable {
//...
public User initGroups() {
Hibernate.initialize(getGroups());
return this;
}
}
以这种方式从Controller调用:User user = userService.getUser(id).initGroups();
选项2。在initGroups()
和UserService
中声明UserDAO
:
UserServiceImpl
@Service
@Transactional
public class UserServiceImpl implements UserService {
//...
@Override
public User initGrupos(User user) {
return userDAO.initGroups(user);
}
}
在UserDAOImpl
@Repository
public class UserDAOImpl implements UserDAO {
//...
@Override
public User initGroups(User user) {
Hibernate.initialize(user.getGroups());
return user;
}
}
以这种方式从Controller调用:
User user = userService.getUser(id);
user = userService.initGroups(user);
结果(两者都相同):
org.hibernate.HibernateException: collection is not associated with any session
org.hibernate.collection.internal.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:484)
org.hibernate.Hibernate.initialize(Hibernate.java:78)
...
答案 0 :(得分:2)
init方法不需要服务,只需要调用Hibernate.initialize,同时保持先前加载对象的Hibernate会话(这是最重要的部分)。