小背景:我使用Spring和Hibernate来创建一个非常简单的域/ dao /服务结构。我还使用Autowiring将所有的豆类注入到他们的开心地点。了解Spring中的SessionFactory
在重构时,最近我尝试访问我的hibernate对象上的FetchType.LAZY属性时,最近出现了一个非常流行的错误消息“无法初始化代理 - 没有会话”。它是这样的:
public class Person {
...
@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
@JoinColumn(name = "pet_id", nullable = false)
public Pet getPet() {
return pet;
}
...
}
我曾经有一个PersonService bean访问Pet属性,并没有这样做的麻烦。不过,我最近重构了代码,以便PersonHelper不用查看Pet,而是PersonHelper查看它。虽然我的帮手bean可以看到PersonDao,但可以拨打电话获取此人,但由于我的会话已关闭,因此无法访问Pet。
所以,我认为我不清楚自己何时休眠会话。所有的配置看起来都很好,而且DAO被注入到我的帮助程序中,就像它用于注入我的服务一样。我不知道为什么我的服务可以让宠物得到好处,但我的帮手不能。
任何帮助理解这个“SessionFactory的奥秘”,非常感谢。我意识到这可能是一个复杂的主题,所以链接到一些好的阅读材料会摇摆。
我已经将代码更改为FetchType.EAGER(正常工作),但是这个谜语在我的大脑中燃烧了整个:)。
每请求,这里是一个(简化)看看我的配置:
<bean id="personSvc" class="org.comp.service.impl.PersonServiceImpl" />
<bean id="personHelper" class="org.comp.service.helper.PersonHelper" />
<bean id="personDao" class="org.comp.dao.hibernate.HibPersonDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
...
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="packagesToScan" value="org.comp.domain"/>
<property name="schemaUpdate" value="true" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider
</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">/hibernate-ehcache.xml</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
DAO被自动连接到帮助:
@Autowired
private PersonDao personDao;
非常有趣。我将研究过滤器,因为这是我不太了解的东西。 – Stephano 2010-07-18 18:56:19
在我正在使用的某个配置中添加。 AnnotationSessionFactoryBean可能看起来有点奇怪,因为我试图简化这篇文章的想法(实际上它有点复杂) – Stephano 2010-07-18 19:03:00
@Stephano - 感谢您的更新。我猜你的DAO是使用HibernateDaoSupport实现的?从这里的细节,我不知道它会如何工作。你可能只是很幸运! (或者更现实的是,还有更多的细节可以澄清这个谜团。是否有任何类型的事务管理?)可能是因为您的DAO正在调用其他DAO,因此会话在第一次调用期间保持打开状态,这会跨越嵌套的调用。相关:http://stackoverflow.com/questions/2145024/lazy-loading-with-spring-hibernatedaosupport – mdma 2010-07-18 19:20:39