LazyInitializationException由于没有在“父”中定义的会话在使用注释的模块化Spring应用程序中的Hibernate 3中的应用程序上下文 [英] LazyInitializationException due to no session defined in "parent" application context in Hibernate 3 in a moduled Spring application using annotations

查看:157
本文介绍了LazyInitializationException由于没有在“父”中定义的会话在使用注释的模块化Spring应用程序中的Hibernate 3中的应用程序上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于Hibernate3和Spring3,我都是新手,我遇到了一个与初始化hibernate对象的懒惰引用相关的问题。



道和服务。域对象是使用hbm2java和逆向工程文件创建的。我遵循了我在服务对象上使用Annotations(@Transactional)的一些最佳实践。 (本指南对我非常有帮助 http:// carinae.net/2009/11/layered-architecture-with-hibernate-and-spring-3/

我遇到的问题是在我的service.jar中,我对注释处理和事务管理有以下的spring配置:

pre $ < 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 =sessionFactoryref =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;

公共列表< ApplicantEvent> getPendingEvents(){
sessionFactory.getCurrentSession()。beginTransaction(); //(如果我没有这个,我的junit测试因为没有活动事务而失败,但这是一个不同的问题)
return sessionFactory.getCurrentSession()
.createQuery(from ApplicantEvent)。名单();






这个代码集合打包成一个maven模块,包括在另一个春季项目中,作为我正在开发的一个调度和工作流程模块的依赖项。相关applicationContext.xml信息

 < bean id =workflowStepperclass =com.barlingbay.merb.scheduler.WorkflowStepper /> 

< bean id =jobDetailWorkflowStepper
class =org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
p:targetObject-ref =workflowStepperp:targetMethod =执行/>

< bean id =triggerJobDetailTicketRegistryCleanerclass =org.springframework.scheduling.quartz.SimpleTriggerBean
p:jobDetail-ref =jobDetailWorkflowStepperp:startDelay =2000
p:repeatInterval =5000/>

< bean id =scheduler
class =com.barlingbay.merb.scheduler.AutowiringSchedulerFactoryBean/>

和一个基本的Workflow.java:

  public class WorkflowStepper实现IWorkflowStepper,
ApplicationContextAware {

private final Logger LOG = Logger.getLogger(this.getClass());
private ApplicationContext applicationContext;

// @Transactional
public void execute(){
ApplicantEventService appEvent =(ApplicantEventService)applicationContext
.getBean(applicantEventServiceImpl);
列表< ApplicantEvent> events = appEvent.getEvents(); (ApplicantEvent事件:事件)
$ b $ {
尝试{
LOG.info(event.getApplicant()。getUsername()+[+ event.getName()
+]);
....

我得到(我明白为什么会得到)LazyInitializationException期间LOG.info语句。该事务由包含的服务maven依赖项中的spring-hibernate上下文管理,并且在此上下文中不可用。我不明白的是将事务管理包含到此层(以及其他)以防止LazyInitializationException的正确方法。我试着简单地添加

 < bean id =txInterceptorclass =org.springframework.transaction.interceptor.TransactionInterceptor/ > 

到业务层的应用程序上下文,它抱怨说它看不到在服务依赖。但是,如果我将@Transactional添加到Workflow步进器的.execute()中,它会从依赖项中继承配置。



我缺少什么?

解决方案

在应用程序中使用OpenEntityManagerInView拦截器进行初始化。否则,您可以在getPendingEvents()方法内的事件列表中的某个ApplicationEvent上调用某个getter方法。这会急切地加载列表中的对象。



编辑:你似乎没有在你的应用程序中使用JPA,所以OpenEntityManagerInView可能不是一个对象。第二个选项应该仍然有效。


I am fairly new to both Hibernate3 and Spring3, and I'm having an issue related to initializing lazy references of a hibernate object.

I have a fully contained dao and service. The domain objects are created using hbm2java and a reverse engineering file. I have followed some best practices I have found using Annotations (@Transactional) on my service objects. (This guide was VERY helpful to me http://carinae.net/2009/11/layered-architecture-with-hibernate-and-spring-3/)

The issue that I am having is that I have the following spring configuration in my service.jar for annotation processing and transaction management:

  <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>

My hibernate.cfg.xml is simply a listing of my datasource details and the annotation mappings of the domain objects.

I am using a service layer and a dao layer.

@Service
public class ApplicantEventServiceImpl implements ApplicantEventService {

  @Autowired(required = true)
  private ApplicantEventDao appEventDao;

  @Transactional
  public List<ApplicantEvent> getEvents() {
    return this.appEventDao.getPendingEvents();
  }

and a dao layer

@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();

  }

This collection of code is packaged as a maven module and is included in as a dependency in another spring project which is a scheduling and workflow module that I am developing. Relevant applicationContext.xml info

<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" />

And a basic 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()
            + "]");
....

I get (and I understand why I get) a LazyInitializationException during the LOG.info statement. The transaction is managed by the spring-hibernate context in the included service maven dependency and is not available in this context. What I don't understand is the proper way to include the transaction management into this layer (and beyond) to prevent the LazyInitializationException. I tried simply adding

<bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor" />

to the business layer's application context, which it complained that it couldn't see the transactionmanager defined in the service dependency. However, if I do add @Transactional to the .execute() of the Workflow stepper, it does "inherit" the configuration from the dependency.

What am I missing?

解决方案

You can fight through Lazy-initialization using an OpenEntityManagerInView interceptor in your application. Else you can call some getter method on one of the ApplicationEvent in the list of events inside the getPendingEvents() method. This will eagerly load the objects inside the lists.

EDIT: You dont seem to use JPA in your application so OpenEntityManagerInView might not be an object. The second option should still work.

这篇关于LazyInitializationException由于没有在“父”中定义的会话在使用注释的模块化Spring应用程序中的Hibernate 3中的应用程序上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆