Java 道、春、冬眠
如果有什么不对劲,请纠正我 现在,当我们使用SpringDAO作为ORM模板时,当我们使用@Transactional属性时, 当在外部而不是在方法内部调用方法时,我们无法控制事务和/或会话 延迟加载节省了资源—减少了对数据库的查询,减少了将所有集合保留在应用程序内存中的内存 因此,如果lazy=false,那么如果一个链接集中有10000条记录,那么所有相关的集合都将被提取,这是无效的 现在,我有一个DAO类中的方法,该方法应该返回一个用户对象。 它具有表示数据库的链接表的集合。 我需要按id获取对象,然后查询其集合 当我尝试访问此DAO方法返回的链接集合时,Hibernate会发生“未能延迟初始化集合”异常 请解释一下,这里的解决方法是什么 更新:好吧,我来问你这个问题。DAO是一个抽象层,因此方法“getUserById(Integer id)”应该返回一个对象 如果在某些情况下我需要这些用户对象的链接集合,而在其他情况下我需要这些集合,该怎么办 只有两种方法: 1) 延迟加载=错误 2) 创建不同的方法:getUserByIdWithTheCollections()、getUserByIdWithOtherCollections(),这些方法内部使用您的方法吗 我的意思是只有两种方法,没有更好的吗 更新2:请解释一下,什么会让我明确使用SESSIONFACTORY? 它在实践中看起来如何?我们创建一个DAO对象的实例, 然后将其注入会话工厂,这将意味着 对DAO的方法调用将在同一事务中运行? 在我看来,不管怎样,DAO与使用它的类是分离的Java 道、春、冬眠,java,hibernate,spring,dao,Java,Hibernate,Spring,Dao,如果有什么不对劲,请纠正我 现在,当我们使用SpringDAO作为ORM模板时,当我们使用@Transactional属性时, 当在外部而不是在方法内部调用方法时,我们无法控制事务和/或会话 延迟加载节省了资源—减少了对数据库的查询,减少了将所有集合保留在应用程序内存中的内存 因此,如果lazy=false,那么如果一个链接集中有10000条记录,那么所有相关的集合都将被提取,这是无效的 现在,我有一个DAO类中的方法,该方法应该返回一个用户对象。 它具有表示数据库的链接表的集合。 我需要按id
逻辑和事务封装在DAO中,对吗?您可以在事务中获取链接的集合,以便在您仍在事务中时加载它:
User user = sessionFactory.getCurrentSession().get(User.class, userId);
user.getLinkedCollection().size();
return user;
正如BalusC所指出的,您可以使用Hibernate.initialize()
而不是size()
。那要干净得多
然后,当您返回这样一个实体时,惰性字段已经初始化
回复您的PS-在服务级别(而不是DAO)级别上使用事务是否可行?似乎是这样,因为在单独的事务中进行每个DAO调用似乎是一种浪费(可能是不正确的)。我发现最好将@Transactional放在服务层,而不是DAO层。否则,所有DAO调用都在单独的hibernate会话中—所有这些对象相等的东西都不起作用。在我看来,解决这个问题的最佳方法是在每个请求的会话模型中设计应用程序。然后,如果您甚至有一个来自DAO的对象,在OSIV模式工作之前,您可以在应用程序中的任何位置安全地使用该对象,即使是在视图中也不必担心这些问题。这可能是提议的更好的解决方案,因为:
您可以执行以下操作:
public User getByUserId(Long id, String ... fetch) {
Criteria criteria = createCriteria();
if (fetch != null) {
for (String fieldName : fetch) {
criteria.setFetchMode(fieldName, FetchMode.JOIN); // fetch these fields eagerly
}
}
return criteria.add(Restrictions.eq("id", id)).list();
}
@康拉德·加鲁斯请看我的问题后记,这里的文字可读性较差,所以我在这里问你。这是处理SpringDAO问题的一个好方法。