Java – can spring / JPA / Hibernate use simple JDBC compatible drivers?
We have an application that uses the spring container on the server. It uses EJB 3 entities and hibernate to persist the data in the PostgreSQL database
I want to use a separate entitymanager to add another connection to a separate database, but the DBMS (trifox vortex) vendor does not have a datasource type driver
Can hibernate entitymanager use a simple JDBC compatible driver to implement EJB3 JPA persistence of entities?
Do I need to use a specific hibernate dialect for the DBMS I am connecting to?
For its value, here is the XML definition of our current spring entity manager factory:
<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 / progress: March 21, 2013
After many exchanges with suppliers, I managed to make their JDBC drivers use simple java test programs
Unfortunately, their jdbc driver is obviously not enough for hibernate to get enough information, because spring cannot create entitymanagerfactory with the following stack trace:
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
So it seems that I may want to write my own dialect subclass Did someone give me any instructions on where to start looking, or extend existing subclasses?
Solution
This should work (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>