2013-03-01 68 views
5

我們有一個應用程序在服務器上使用Spring容器,它使用EJB3實體和Hibernate在PostgreSQL數據庫中保存數據。Spring/JPA/Hibernate可以使用簡單的JDBC兼容驅動程序嗎?

我想使用單獨的EntityManager將另一個連接添加到單獨的數據庫,但DBMS(Trifox Vortex)的供應商沒有DataSource類型驅動程序。

Hibernate EntityManager可以使用簡單的JDBC兼容驅動程序來實現實體的EJB3 JPA持久性嗎?

我需要爲我連接的DBMS具有特定的Hibernate方言嗎?

對於它的價值,這裏是我們當前實體管理器工廠的春季XML定義:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceUnitName" value="UniWorks-EntityPersistenceUnit"/> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="jpaDialect"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> 
    </property> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
     <property name="showSql" value="${db.showsql}"/> 
     <property name="generateDdl" value="${db.generate}"/> 
     <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect"/> 
     </bean> 
    </property> 
    <property name="jpaProperties"> 
     <props> 
     <prop key="hibernate.hbm2ddl.auto">${db.hbm2ddl}</prop> 
     </props> 
    </property> 
    </bean> 

UPDATE /進展情況: 21/3/13

後多少-ING和與供應商一起,我設法讓他們的JDBC驅動程序與一個簡單的Java測試程序一起工作。

不幸的是,他們的JDBC驅動程序顯然是不足夠的Hibernate來獲得足夠的信息,春節無法創建與以下堆棧跟蹤EntityManagerFactory的:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in URL [bundle://222.0:0/META-INF/spring/cobol.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: UniWorks-CobolPersistenceUnit] Unable to build EntityManagerFactory 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)[58:org.springframework.beans:3.1.1.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)[58:org.springframework.beans:3.1.1.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)[58:org.springframework.beans:3.1.1.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)[58:org.springframework.beans:3.1.1.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)[58:org.springframework.beans:3.1.1.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)[58:org.springframework.beans:3.1.1.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)[58:org.springframework.beans:3.1.1.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)[58:org.springframework.beans:3.1.1.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)[59:org.springframework.context:3.1.1.RELEASE] 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:69)[90:org.springframework.osgi.core:1.2.1] 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:355)[90:org.springframework.osgi.core:1.2.1] 
    at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)[90:org.springframework.osgi.core:1.2.1] 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)[90:org.springframework.osgi.core:1.2.1] 
    at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:132)[91:org.springframework.osgi.extender:1.2.1] 
    at java.lang.Thread.run(Thread.java:662)[:1.6.0_24] 
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: UniWorks-CobolPersistenceUnit] Unable to build EntityManagerFactory 
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677)[80:com.springsource.org.hibernate:3.3.2.GA] 
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:132)[80:com.springsource.org.hibernate:3.3.2.GA] 
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:268)[64:org.springframework.orm:3.1.1.RELEASE] 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)[64:org.springframework.orm:3.1.1.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)[58:org.springframework.beans:3.1.1.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)[58:org.springframework.beans:3.1.1.RELEASE] 
    ... 14 more 
Caused by: org.hibernate.HibernateException: Unable to access java.sql.DatabaseMetaData to determine appropriate Dialect to use 
    at org.hibernate.dialect.resolver.DialectFactory.determineDialect(DialectFactory.java:141)[80:com.springsource.org.hibernate:3.3.2.GA] 
    at org.hibernate.dialect.resolver.DialectFactory.buildDialect(DialectFactory.java:97)[80:com.springsource.org.hibernate:3.3.2.GA] 
    at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:117)[80:com.springsource.org.hibernate:3.3.2.GA] 
    at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2119)[80:com.springsource.org.hibernate:3.3.2.GA] 
    at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2115)[80:com.springsource.org.hibernate:3.3.2.GA] 
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1339)[80:com.springsource.org.hibernate:3.3.2.GA] 
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)[80:com.springsource.org.hibernate:3.3.2.GA] 
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)[80:com.springsource.org.hibernate:3.3.2.GA] 
    ... 19 more 
Caused by: java.sql.SQLException: getDatabaseMajorVersion: Not supported by VORTEXjdbc. 
    at vortex.sql.vortexDbMetaData.getDatabaseMajorVersion(vortexDbMetaData.java:362) 
    at org.hibernate.dialect.resolver.DialectFactory.determineDialect(DialectFactory.java:131)[80:com.springsource.org.hibernate:3.3.2.GA] 
    ... 26 more 

所以看起來我可能會寫我的自己的方言子類。任何人都可以提供關於從哪裏開始尋找的指示,或者現有的哪些子類可以擴展?

回答

3

這應該工作(SimpleDriverDataSource + org.springframework.orm.jpa.vendor.Database.DEFAULT):

<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"> 
     <property name="driverClass" value="org.h2.Driver"/> <!-- put your driver here --> 
     <property name="url" value="jdbc:h2:mem:test"/> <!-- put your jdbc url here --> 
     <property name="username" value="sa"/> 
     <property name="password" value=""/> 
    </bean> 

      <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="dataSource" ref="dataSource"/> 
     <property name="persistenceUnitName" value="TestPersistenceUnit"/> 
     <property name="jpaDialect"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> 
     </property> 
     <property name="jpaVendorAdapter"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
       <property name="showSql" value="false"/> 
       <property name="database" value="DEFAULT"/> 
      </bean> 
     </property> 
    </bean> 
+0

感謝您的回答。在給予獎勵之前,我會嘗試設置一個工作示例來測試你的理論,但如果它看起來不像我會在截止日期之前到達那裏,我會無論如何給你。乾杯。 – DuncanKinnear 2013-03-11 21:26:16

+0

得到任何分數? :) – 2013-03-17 21:13:01

+0

我給你的賞金,因爲你提供的代碼肯定讓我遠遠超出了我的預期。在這個階段,我可以看到(從堆棧跟蹤中)Spring正在調用hibernate,它正在創建簡單的驅動程序數據源,但目前實際的驅動程序本身拋出了有關用戶名和密碼的錯誤,所以我認爲我們是就快到了。 – DuncanKinnear 2013-03-17 22:27:29

0

Hibernate可以使用比其他數據源連接池。所以你可以使用c3p0或者proxool或者dbcp甚至你自己的連接池。 Hibernate確實有一個內置的連接池,儘管它只用於測試/原型設計;它可以讓你只傳入驅動程序名稱,網址,用戶名,密碼,它會設置一些(非常)簡單的池。

有幾個不同的選項來實現這一點。首先,Hibernate始終通過統一合同來處理獲取和釋放連接:org.hibernate.engine.jdbc.connections.spi.ConnectionProvider。所以一個選擇是傳遞你自己的ConnectionProvider實現。

另一種選擇是傳入驅動程序,url,用戶名,密碼和ConnectionProvider以供使用。對於驅動程序,url,用戶名和密碼都Hibernate和JPA定義機制來做到這一點。對於JPA,您可以使用persistence.xml或設置javax.persistence.jdbc.driver,javax.persistence.jdbc.url,javax.persistence.jdbc.userjavax.persistence.jdbc.password。就ConnectionProvider而言,默認情況下,Hibernate將選擇不支持的,不打算用於生產的。但要告訴休眠一個不同的使用,你可以使用hibernate.connection.provider_class設置。 Hibernate內置了對c3p0和proxool進行集成的支持,作爲後端連接池(Hibernate將爲您設置和管理c3p0/proxool池並使用該池進行連接管理)。

正如其他答案指出的那樣,另一種選擇是在驅動程序和連接信息周圍使用DataSource包裝器。

對不起,我不知道Spring,所以我不知道指定persistence.xml或JPA設置或Hibernate設置的所有Spring特定方法。

相關問題