GWT 开发模式 + Spring 3.1 + Hibernate 4.0.1 中的异常

Posted

技术标签:

【中文标题】GWT 开发模式 + Spring 3.1 + Hibernate 4.0.1 中的异常【英文标题】:Exception in GWT Dev Mode + Spring 3.1 + Hibernate 4.0.1 【发布时间】:2012-02-12 01:41:30 【问题描述】:

我有一个 GWT+Hibernate+JPA+Spring 配置文件,它适用于 Spring 3.0.x + Hibernate 3.6.x。当我升级到 Spring 3.1 和 Hibernate 4.0 时,抛出以下异常:

Hibernate 4 和 Spring 3.1 是否存在任何已知的不兼容性?

org.springframework.beans.factory.BeanCreationException:在类路径资源 [META-INF/application-context.xml] 中定义名称为“entityManagerFactory”的 bean 创建错误:调用 init 方法失败;嵌套异常是 javax.persistence.PersistenceException: [PersistenceUnit: myPu] Unable to build EntityManagerFactory 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 在 org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567) 在 org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913) 在 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) 在 org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:384) 在 org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283) 在 org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) 在 org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:543) 在 org.mortbay.jetty.servlet.Context.startContext(Context.java:136) 在 org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1220) 在 org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:513) 在 org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448) 在 com.google.gwt.dev.shell.jetty.JettyLauncher$WebAppContextWithReload.doStart(JettyLauncher.java:468) 在 org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39) 在 org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130) 在 org.mortbay.jetty.handler.RequestLogHandler.doStart(RequestLogHandler.java:115) 在 org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39) 在 org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130) 在 org.mortbay.jetty.Server.doStart(Server.java:222) 在 org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39) 在 com.google.gwt.dev.shell.jetty.JettyLauncher.start(JettyLauncher.java:672) 在 com.google.gwt.dev.DevMode.doStartUpServer(DevMode.java:509) 在 com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:1068) 在 com.google.gwt.dev.DevModeBase.run(DevModeBase.java:811) 在 com.google.gwt.dev.DevMode.main(DevMode.java:311) 引起:javax.persistence.PersistenceException: [PersistenceUnit: naftPu] 无法构建 EntityManagerFactory 在 org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914) 在 org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:889) 在 org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73) 在 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:257) 在 org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) ... 30 更多 原因:org.hibernate.service.spi.ServiceException:无法创建请求的服务 [org.hibernate.service.jdbc.connections.spi.ConnectionProvider] 在 org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:187) 在 org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:150) 在 org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131) 在 org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:234) 在 org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:91) 在 org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75) 在 org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159) 在 org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131) 在 org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:71) 在 org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2270) 在 org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2266) 在 org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1735) 在 org.hibernate.ejb.EntityManagerFactoryImpl.(EntityManagerFactoryImpl.java:84) 在 org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904) ... 36 更多 原因:org.hibernate.HibernateException:无法实例化连接提供程序 [org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider] 在 org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator.instantiateExplicitConnectionProvider(ConnectionProviderInitiator.java:190) 在 org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:112) 在 org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator.initiateService(ConnectionProviderInitiator.java:54) 在 org.hibernate.service.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:69) 在 org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:177) ... 49 更多 引起:java.lang.ClassCastException:org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider 不能转换为 org.hibernate.service.jdbc.connections.spi.ConnectionProvider 在 org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator.instantiateExplicitConnectionProvider(ConnectionProviderInitiator.java:187) ... 53 更多

这是我的 application-context.xml 配置的一部分:

<bean id="mainDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
    <property name="url" value="***manually deleted***" />
    <property name="username" value="myschema" />
    <property name="password" value="myschema" />
    <property name="initialSize" value="1" />
    <property name="maxActive" value="4" />
    <property name="maxIdle" value="-1" />
    <property name="maxWait" value="10000" />
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:persistenceUnitName="myPu">
    <property name="dataSource" ref="mainDataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" p:showSql="true" p:generateDdl="true"
            p:database="ORACLE" p:databasePlatform="org.hibernate.dialect.Oracle10gDialect" />
    </property>
    <property name="jpaPropertyMap">
        <map merge="true">
            <entry key="hibernate.archive.autodetection" value="class" />
            <entry key="hibernate.format_sql" value="false" />
            <entry key="hibernate.hbm2ddl.auto" value="false" />
            <entry key="hibernate.default_schema" value="myschema" />
        </map>
    </property>
</bean>

persistence.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
    <persistence-unit name="myPu" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
    </persistence-unit>
</persistence>

【问题讨论】:

粘贴 mainDataSource bean 配置和 persistence.xml。你的服务器是什么?你完全使用 EJB 吗?这个类很奇怪:org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider。我发现了什么:relation.to/Bloggers/SomeTipsOnUsingHibernateInJBossAS700Final 看起来像这样:org.hibernate.ejb.HibernatePersistence 是错误的提供者。 @peter-gwiazda 谢谢,该页面没有帮助,因为我不在 JBoss 之外。顺便说一句,除了 org.hibernate.ejb.HibernatePersistence 之外,没有其他用于 Hibernate 的 JPA 提供程序。 你在使用 maven 和 gwt 和 jetty 插件吗? 我也有同样的问题,而且只有在 GWT Dev 模式下运行时才会出现。当我在自己的码头以生产模式运行它时,它工作正常。我认为类路径有问题,但我不知道它是什么。 【参考方案1】:

此问题已修复in Hibernate 4.1.4。


我遇到了同样的问题,它似乎与 Jetty 类加载器(GWT 插件使用 Jetty 进行托管模式)、GWT 插件和 Hibernate(尽管它显然也与其他库一起出现)有关。

它类似于这里提到的错误Hibernate Bug Report,但在我们的例子中,我们通过 GWT 插件运行它,它会导致 ConnectionProvider 的 ClassCastException。

错误报告中提到的修复应该可以解决该特定问题。

对于 org.hibernate.service.classloading.internalClassLoaderServiceImpl,通过构造函数将 parent 设置为 null:

this.classClassLoader = new ClassLoader(null) 
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException 
            for ( ClassLoader loader : classLoadingClassLoaders ) 
                try 
                    return loader.loadClass( name );
                
                catch (Exception ignore) 
                
            
            throw new ClassNotFoundException( "Could not load requested class : " + name );
        
;

【讨论】:

这已在休眠 4.1.4 中修复【参考方案2】:

删除 /lib 目录中的 ejb3-persistence.jar(如果已经存在);它与 hibernate 4 中的 hibernate-jpa-2.0-api-1.0.1.Final.jar 冲突。在遇到此问题后这对我有用,我实现了在 Openshift 环境中托管 GWT、Hibernate 4、Spring 3.1.1 应用程序@ 987654321@

【讨论】:

【参考方案3】:

我认为您不需要在persistence.xml 中设置&lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;/provider&gt;。检查the docs。

【讨论】:

没有变化。当类路径中有多个提供者时,此元素可帮助 JPA 决定选择哪个提供者。

以上是关于GWT 开发模式 + Spring 3.1 + Hibernate 4.0.1 中的异常的主要内容,如果未能解决你的问题,请参考以下文章

IE8 的 GWT 开发模式

GWT 2.7 超级开发模式不适用于 CssResource.style=obf

将 spring 3 mvc 与 GWT 集成的经验?

GWT 超级开发模式 - bindAddress - 未显示更改

GWT 2.4 与 Spring 的集成

Intellij 12、GWT 2.6.0-rc1 和超级开发模式