当前位置: 首页 > 知识库问答 >
问题:

Java独立(控制台)应用程序-org.hibernate.lazyInitializationException:无法初始化代理-没有会话

毛博
2023-03-14

我搜索了所有的StackOverflow站点和Google,99.9%的问题都是关于web应用程序的,但对于经典异常“org.hibernate.lazyInitializationException:could not initialize proxy-no session”,Java独立应用程序(运行于Linux终端“Java-jar myapp.jar”)没有找到任何解决方案

我的项目使用的是spring 4.0.7+Hibernate 4.3.6.Final+Log4J 1.2.17+BoneCP 0.8.0

我尝试过以下几种解决方案:

    客户端类中的
  1. @service@transactional批注,以及客户端类调用的类中的批注;
  2. 客户端类中的
  3. @service@transactional(propagation=propagation.required)批注,以及该客户端类的类中的批注;
  4. @服务切换到@组件并重试了上面的项目%1和%2;
  5. 尝试使用TransactionTemplate并在TransactionCallback.DoInTransaction()方法中执行Client.Start()方法;
  6. 我已尝试从客户端类中删除@service@transactional以及从客户端类调用的类中删除。

我已经尝试了所有这些操作,但仍然正在获取org.hibernate.LazyInitializationException:无法初始化代理-没有会话

代码中的注释也是我尝试过的。

重要提示:项目使用一个Facade类,它包含应用程序使用的所有方法。

spring配置由以下XML加载:


    <beans>
        <context:annotation-config />
        <context:component-scan base-package="com.mycompany" />
        <context:property-placeholder location="classpath:persistence.properties" />
        <tx:annotation-driven transaction-manager="transactionManager" />

        <!-- BoneCP -->
        <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
            <property name="driverClass" value="${jdbc.driverClassName}"/>
            <property name="jdbcUrl" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
            <property name="idleConnectionTestPeriodInMinutes" value="60"/>
            <property name="idleMaxAgeInMinutes" value="240"/>
            <property name="maxConnectionsPerPartition" value="30"/>
            <property name="minConnectionsPerPartition" value="10"/>
            <property name="partitionCount" value="3"/>
            <property name="acquireIncrement" value="5"/>
            <property name="statementsCacheSize" value="100"/>
            <property name="releaseHelperThreads" value="3"/>
        </bean>

        <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="packagesToScan" value="com.mycompany.domain.entity" />
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                    <prop key="hibernate.default_schema">${hibernate.default_schema}</prop>
                    <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                    <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
                    <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
                    <prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
                    <!-- I have tried setting "current_session_context_class", but still getting "org.hibernate.LazyInitializationException: could not initialize proxy - no Session" -->
                    <!-- <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop> -->
                </props>
            </property>
       </bean>

       <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
          <property name="sessionFactory" ref="sessionFactory" />
          <property name="dataSource" ref="dataSource" />
       </bean>

        <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
            <property name="transactionManager" ref="transactionManager"/>
        </bean>

       <bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

        <bean id="client" class="com.mycompany.console.Client" />
    </beans>

项目主类:



    package com.mycompany.console;

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;

    @Service
    @Transactional(propagation = Propagation.REQUIRED)
    public class Client {
        private static final Logger logger = Logger.getLogger(Client.class);

        public static void main(String args[]) {
            ApplicationContext applicationContext = null;

            // Load Spring application context
            try {
                applicationContext = new ClassPathXmlApplicationContext("springHibernateConfig.xml");

                final Client client = applicationContext.getBean("client"); // Or applicationContext.getBean(Client.class)

    // Already tried using TransactionTemplate, but still getting "org.hibernate.LazyInitializationException: could not initialize proxy - no Session"
    //          TransactionTemplate transactionTemplate = (TransactionTemplate) applicationContext.getBean("transactionTemplate");
    //          transactionTemplate.execute(new TransactionCallback() {
    //              @Override
    //              public Object doInTransaction(TransactionStatus status) {
    //                  client.start(args);
    //                  return null;
    //              }
    //          });
                client.start(args);

            } catch (Exception e) {
                System.err.println("Error loading Spring application context: " + e.getMessage());
                e.printStackTrace();
                System.exit(1);
            }
        }

        private void start(String args[]) {
            // List, Save, Update, Delete entities
            // 
            // Calls Facade.instance().getUserById(1L), for example
            // 
            // [...]
        }
    }


门面类(ABDomain):



    package com.mycompany.domain.facade;

    @Service
    @Transactional(propagation = Propagation.REQUIRED)
    public class ABDomain {

        public static ABDomain instance() {
            // SpringUtil implements ApplicationContextAware
            return SpringUtil.getApplicationContext().getBean(ABDomain.class);
        }

        public User getUserById(Long id) {
            /*
                UsuarioDao is an interface, and its 
                implementation UsuarioDaoImpl extends AbstractHibernateDao
            */
            return Registry.getUserDao().findById(id);
        }
    }


注册表类:



    package com.mycompany.domain.registry;

    @Component
    @Transactional
    public class Registry {

        private static ApplicationContext applicationContext;

        @Autowired(required = true)
        public Registry(ApplicationContext appContext) {
            applicationContext = appContext;
        }

        public static UserDao getUserDao() {
            return applicationContext.getBean(UserDao.class);
        }
    }


编辑:

添加堆栈跟踪以更好地理解。

注:

  • ABDomain是应用程序外观(上面提到过)。
  • 收件箱是另一个由客户端类调用的类
org.springframework.orm.hibernate4.HibernateSystemException: could not initialize proxy - no Session; nested exception is org.hibernate.LazyInitializationException: could 
not initialize proxy - no Session
        at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:216)
        at org.springframework.orm.hibernate4.HibernateExceptionTranslator.convertHibernateAccessException(HibernateExceptionTranslator.java:57)
        at org.springframework.orm.hibernate4.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:44)
        at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
        at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
        at com.sun.proxy.$Proxy120.findLastPosition(Unknown Source)
        at com.mycompany.domain.facade.ABDomain.findLastPosition(ABDomain.java:832)
        at com.mycompany.domain.facade.ABDomain$$FastClassBySpringCGLIB$$f56e1d49.invoke()
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
        at com.mycompany.domain.facade.ABDomain$$EnhancerBySpringCGLIB$$4c071cee.findLastPosition()
        at com.mycompany.cpr.client.Inbox.updateLastPosition(Inbox.java:714)
        at com.mycompany.cpr.client.Inbox.processMessage(Inbox.java:604)
        at com.mycompany.cpr.client.Inbox$3.run(Inbox.java:934)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
        at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165)
        at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
        at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
        at com.mycompany.domain.entity.Vehicle_$$_jvst374_1e.getId(Vehicle_$$_jvst374_1e.java)
        at com.mycompany.domain.dao.impl.LastPositionDaoImpl.findLastPosition(LastPositionDaoImpl.java:34)
        at sun.reflect.GeneratedMethodAccessor1487.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)

编辑2:

Inbox是一个由Client类(主类)调用的类。收件箱没有注释,但我已经尝试了@service@transactional或@component@transactional注释。我正在寻找web项目中常用的类似OpenSessionInViewFilter的解决方案。

共有1个答案

商开济
2023-03-14

在分析了堆栈跟踪之后,我看到TransactionInterceptor被调用了,所以唯一可能的解释是,如果您尝试初始化一个在不同于当前会话的会话中加载的eneityt:

因此,您调用的这个方法:at com.mycompany.domain.dao.impl.LastPositionDaoImpl.FindLastPosition(LastPositionDaoImpl.java:34)

车辆实体是否加载到不同的线程/事务/会话中,然后发送到您截取的消息中:

at com.mycompany.cpr.client.Inbox.processMessage(Inbox.java:604)

如果是这种情况,您需要初始化生产者事务中所有想要的关联(获取车辆并发送车辆的关联)。

 类似资料:
  • 问题内容: 我有2台物理服务器,我的Web应用程序命中该服务器由负载均衡器管理。我总是得到- org.hibernate.LazyInitializationException:无法初始化代理-没有会话 当其中一台服务器受到攻击而另一台服务器运行平稳而没有任何问题时。我有一个由应用程序启用和管理的本地托管缓存存储。仅当尝试从一个表访问一个特定的列时,才会发生此异常。不管选择哪个服务器,其余的操作都

  • 问题内容: 我试图从数据库中的对象进行简单加载,但出现错误“无法初始化代理-没有会话”,知道吗?谢谢 问题答案: 尝试添加到validate方法: 发生的事情是,因为没有注释,所以没有与该方法关联的会话,并且每个查询都将在其自己的会话中运行,该会话随后将立即关闭。 该方法始终返回一个代理,与之不同(请参阅此处,了解load与get之间的差异)。 因此,返回了代理,但是由于缺少代理,因此立即关闭了创

  • 我试图从DB中的一个对象做一个简单的加载,但是我得到的错误是“Could not initialize proxy-no session”,有什么想法吗?谢谢

  • 我正在尝试使用Primeface JSF Spring Boot做一个示例User CRUD页面。在页面上,我有一个启用LazyLoding的表。我的User对象没有1对N或N对1字段,都是原始字段,在到达时不需要数据库访问或初始化。(所以FetchType.EAGER不会有帮助) 当试图在弹出窗口上显示用户列表中的用户时,出现以下异常: 为什么 JSF 组件尝试从数据库中更新对象以获取 1 比

  • 问题内容: 对数据库有以下查询: 在获取employee.address.street,employee.address.houseNumber或employee.address.city时,它将失败,但以下情况除外: 员工映射: 地址映射: 对于其他类(办公室,公司等),这​​是绝对正常的。如果注释,则在jsp应用程序中加载地址字段的行将正常工作。怎么了?顺便说一下,尽管有异常,它仍显示有关js

  • 抱歉,如果我的帖子是重复的,但我不能从另一个主题解决我的问题,所以我创建了这个主题。希望有人帮助我。我用的是Hibernate,JSF和Glassfish。 这是我的完整代码 CusterBean(请求范围) 顾客道 xhtml 我得到这个错误: SEVERE:javax.el.ELException: /admin/customer_list.xhtml@68,106 value="#{cust