Немного предыстории: я использую Spring и Hibernate для создания действительно простой структуры домен / дао / сервис. Я также использую Autowiring для ввода всех своих бобов в их счастливые места.
Во время рефакторинга я недавно получил слишком популярное сообщение об ошибке «Не удалось инициализировать прокси - нет сеанса» при попытке доступа к свойству FetchType.LAZY в моем спящем объекте. Это выглядит примерно так:
public class Person {
...
@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
@JoinColumn(name = "pet_id", nullable = false)
public Pet getPet() {
return pet;
}
...
}
Раньше у меня был компонент PersonService, который обращался к свойству Pet, и у меня не было проблем с этим. Тем не менее, я недавно провела рефакторинг кода, чтобы вместо PersonService, смотрящего на Pet, PersonHelper смотрел на него. В то время как мой компонент-помощник может видеть PersonDao, он может позвонить, чтобы получить человека, но он не может получить доступ к питомцу, так как моя сессия закрыта.
Итак, я думаю, что мне непонятно, когда я теряю свою спящую сессию. Все конфиги выглядят нормально, и DAO внедряется в моего помощника, точно так же, как он использовался для моего сервиса. Я не уверен, почему мой сервис мог получить Pet просто отлично, но мой помощник не может.
Любая помощь с пониманием этой "тайны 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;