私は Hibernate3 と Spring3 の両方にかなり慣れていませんが、休止状態オブジェクトの遅延参照の初期化に関連する問題があります。
私は完全に含まれているdaoとサービスを持っています。ドメイン オブジェクトは、hbm2java とリバース エンジニアリング ファイルを使用して作成されます。サービス オブジェクトで注釈 (@Transactional) を使用して見つけたいくつかのベスト プラクティスに従いました。(このガイドは私にとって非常に役に立ちましたhttp://carinae.net/2009/11/layered-architecture-with-hibernate-and-spring-3/ )
私が抱えている問題は、アノテーション処理とトランザクション管理のために、service.jar に次のスプリング構成があることです。
<context:annotation-config />
<context:component-scan base-package="com.barlingbay.dodmerb.persistence" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<tx:annotation-driven/>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
私の hibernate.cfg.xml は、データソースの詳細とドメイン オブジェクトの注釈マッピングの単なるリストです。
サービスレイヤーとdaoレイヤーを使用しています。
@Service
public class ApplicantEventServiceImpl implements ApplicantEventService {
@Autowired(required = true)
private ApplicantEventDao appEventDao;
@Transactional
public List<ApplicantEvent> getEvents() {
return this.appEventDao.getPendingEvents();
}
そしてdaoレイヤー
@Repository
public class ApplicantEventDaoImpl implements ApplicantEventDao {
@Autowired(required = true)
private SessionFactory sessionFactory;
public List<ApplicantEvent> getPendingEvents() {
sessionFactory.getCurrentSession().beginTransaction(); // (If I don't have this, my junit test fails because of no active transaction, but that's a different issue)
return sessionFactory.getCurrentSession()
.createQuery("from ApplicantEvent").list();
}
このコードのコレクションは、maven モジュールとしてパッケージ化されており、私が開発しているスケジューリングおよびワークフロー モジュールである別の spring プロジェクトに依存関係として含まれています。関連する applicationContext.xml 情報
<bean id="workflowStepper" class="com.barlingbay.merb.scheduler.WorkflowStepper" />
<bean id="jobDetailWorkflowStepper"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
p:targetObject-ref="workflowStepper" p:targetMethod="execute" />
<bean id="triggerJobDetailTicketRegistryCleaner" class="org.springframework.scheduling.quartz.SimpleTriggerBean"
p:jobDetail-ref="jobDetailWorkflowStepper" p:startDelay="2000"
p:repeatInterval="5000" />
<bean id="scheduler"
class="com.barlingbay.merb.scheduler.AutowiringSchedulerFactoryBean" />
そして、基本的な Workflow.java:
public class WorkflowStepper implements IWorkflowStepper,
ApplicationContextAware {
private final Logger LOG = Logger.getLogger(this.getClass());
private ApplicationContext applicationContext;
// @Transactional
public void execute() {
ApplicantEventService appEvent = (ApplicantEventService) applicationContext
.getBean("applicantEventServiceImpl");
List<ApplicantEvent> events = appEvent.getEvents();
for (ApplicantEvent event : events) {
try {
LOG.info(event.getApplicant().getUsername() + "[" + event.getName()
+ "]");
....
LOG.info ステートメントの実行中に LazyInitializationException が発生しました (なぜ取得したのか理解しています)。トランザクションは、含まれているサービス maven 依存関係の spring-hibernate コンテキストによって管理され、このコンテキストでは使用できません。私が理解していないのは、LazyInitializationException を防ぐためにトランザクション管理をこのレイヤー (およびそれ以降) に含める適切な方法です。単純に追加してみました
<bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor" />
ビジネス層のアプリケーション コンテキストに、サービスの依存関係で定義されたトランザクション マネージャーが表示されないことを訴えました。ただし、ワークフローステッパーの .execute() に @Transactional を追加すると、依存関係から構成が「継承」されます。
私は何が欠けていますか?