【发布时间】:2010-07-18 18:30:07
【问题描述】:
一点背景知识:我正在使用 Spring 和 Hibernate 创建一个非常简单的 domain/dao/service 结构。我还使用自动装配将我所有的 bean 注入他们快乐的地方。
在重构时,我最近在尝试访问我的休眠对象上的 FetchType.LAZY 属性时收到了非常流行的错误消息“无法初始化代理 - 无会话”。它是这样的:
public class Person {
...
@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
@JoinColumn(name = "pet_id", nullable = false)
public Pet getPet() {
return pet;
}
...
}
我曾经有一个访问 Pet 属性的 PersonService bean,并且这样做没有问题。但是,我最近重构了代码,以便 PersonHelper 不再查看 Pet,而是查看 Pet。虽然我的助手 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;
【问题讨论】: