Spring Autowiring停止了GAE的工作

时间:2012-03-20 08:53:37

标签: spring hibernate google-app-engine autowired

我确信我的应用程序工作正常,直到昨天我收到此错误:

  

上下文启动失败   com.google.apphosting.utils.jetty.RuntimeAppEngineWebAppContext@1079ff {/,/   基地/数据/家/应用/秒〜trewnewmedia / 1.357617962256387950}   org.springframework.beans.factory.BeanCreationException:错误   创建名为'scadenziarioController'的bean:注入   自动连接依赖失败;嵌套异常是   org.springframework.beans.factory.BeanCreationException:不能   autowire方法:public void   it.trew.prove.web.controllers.ScadenziarioController.setScadenzaService(它。   trew.prove.services.ScadenzaService);嵌套异常是   org.springframework.beans.factory.BeanCreationException:错误   创建名为'scadenzaService'的bean:注入autowired   依赖失败;嵌套异常是   org.springframework.beans.factory.BeanCreationException:不能   autowire方法:public void   it.trew.prove.services.ScadenzaService.setSocietaService(it.trew.prove.serv   ices.SocietaService);嵌套异常是   org.springframework.beans.factory.BeanCreationException:错误   创建名为'societaService'的bean:注入autowired   依赖失败;嵌套异常是   org.springframework.beans.factory.BeanCreationException:不能   autowire方法:public void   it.trew.prove.services.SocietaService.setSocietaDao(it.trew.prove.model.dao   .Dao);嵌套异常是   org.springframework.beans.factory.BeanCreationException:错误   创建名为'dao'的bean:注入资源依赖项   失败;嵌套异常是   org.springframework.beans.factory.BeanCreationException:错误   创建名为'mySessionFactory'的bean:后处理   FactoryBean的对象失败;嵌套异常是   java.lang.SecurityException:无法获取类的成员   org.hibernate.impl.SessionFactoryImpl

我正在使用Hibernate和Google Cloud SQL,它始终有效。

在我的本地计算机上,使用本地MySQL,它仍然有效!

我不认为这是一个Cloud SQL问题,因为删除了一些仍然连接的自动装配(测试),依此类推。这是我的xml:

<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="myDataSource" />
        <property name="annotatedClasses">
            <list>
                <value>it.trew.prove.model.beans.Scadenza</value>
                <value>it.trew.prove.model.beans.Fornitore</value>
                <value>it.trew.prove.model.beans.Societa</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <!-- <prop key="hibernate.hbm2ddl.import_files">/setup.sql</prop> -->
            </props>
        </property>
    </bean>

我的DAO:

@Component
public class Dao {

    @Resource(name = "mySessionFactory")
    private SessionFactory sessionFactory;
...

我的服务:

@Service
@Transactional
public class SocietaService {

    private Dao societaDao;

    @Autowired
    public void setSocietaDao(Dao societaDao) {
        this.societaDao = societaDao;
    }
...

我找不到GAE和我的本地(mvn gae:run)之间有什么不同。 为什么上周工作得很好。

请GAE团队,支持我!我在这个问题上发疯了

(我可能会开始赏金,这太紧急了)

编辑我的pom.xml hibernate部分:

<!-- Hibernate framework -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.3.2.GA</version>
        <type>pom</type>
        <!--hibernate-dependencies is a pom, not needed for hibernate-core-->
      </dependency>
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.4.0.GA</version>
    </dependency>
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.12.1.GA</version>
    </dependency>

3 个答案:

答案 0 :(得分:3)

似乎SessionFactoryImpl引用了一个google上没有的类的whiteliste,并且在这种情况下它无法加载。

以下是关于此的文章:http://googlecloudsql.blogspot.de/

答案 1 :(得分:1)

法比奥帮助我指出了正确的方向。我发现使用@Transactional的声明性事务在GAE中不起作用,因为Spring会扫描org.hibernate.impl.SessionFactoryImpl,这会导致加载不在GAE白名单中的javax.naming类。我有同样的问题切换到基于XML的声明。所以我最终使用TransactionTemplate对象进行程序化事务管理,这似乎正在发挥作用。

编辑:添加了代码示例

从我的弹簧配置中,我删除了<tx:annotation-driven/>以禁用@Transactional并将其替换为

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

如果您正在使用多个事务语义,例如PROPAGATION_REQUIRED和PROPAGATION_SUPPORTS,你必须创建额外的bean,每个场景一个,例如。

<bean id="supportingTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="propagationBehaviorName" value="PROPAGATION_SUPPORTS"/>
    <property name="transactionManager"><ref local="transactionManager"/></property>
</bean>

我使用@Transactional表示法离开了原始服务类。自<tx:annotation-driven/>被移除后无关紧要,如果问题得到解决,我可能会在某一天切换回来。相反,我让他们使用TransactionTemplate

public class GAEUserService extends UserService {

    @Autowired
    private TransactionTemplate defaultTransactionTemplate;

    @Override
    public void update(final User user) {
        defaultTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                UserService.super.update(user);
            }
        });
    }
}

我发现的一个缺点是我必须将我的服务方法抛出的已检查异常转换为未经检查的异常,因为已检查的异常与doInTransactionWithoutResult的签名不一致

答案 2 :(得分:0)

问题是@Service类上的@Transactional注释。它在某些我不知道的部分使用了javax.naming.NamingException,而且这不是列入白名单的类。