我在apache tomcat5.5上使用Spring 2.0.6和Hibernate 3.2.x,现在我们计划将我们的hybernate映射文件更改为hybernate + jpa支持映射文件。为此,我们创建了这样的文件
daoConfig.xml
<beans:bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <beans: property name="jndiName"> <beans: value>java:/comp/jdbc/Paymentsdb</beans:value> </beans: property> </beans: bean> <beans: bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <beans: property name="useTransactionAwareDataSource" value="true" /> <beans: property name="dataSource"> <beans:ref bean="dataSource"/> </beans: property> <beans: property name="hibernateProperties"> <beans: props> <beans:prop key="hibernate.dialect">${database.target}</beans:prop> <beans:prop key="hibernate.connection.isolation">3</beans:prop> <beans:prop key="hibernate.current_session_context_class">jta</beans:prop> <beans:prop key="hibernate.transaction.factory_class">com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory </beans:prop> <beans: prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup </beans: prop> <beans: prop key="hibernate.connection.release_mode">on_close</beans: prop> <beans: prop key="hibernate.show_sql">false</beans: prop> </beans: props> </beans: property> </beans: bean> <beans: bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate"> <beans: property name="entityManagerFactory"> <beans:ref bean="entityManagerFactory" /> </beans: property> </beans: bean> <beans: bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <beans: property name="dataSource"> <beans:ref bean="dataSource" /> </beans: property> <beans: property name="jpaVendorAdapter"> <beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <beans: property name="generateDdl" value="false"/> <beans: property name="showSql" value="true" /> <beans: property name="databasePlatform" value="${database.target}" /> </beans: bean> </beans: property> <beans: property name="persistenceXmlLocation"> <beans:value>classpath:META-INF/persistence.xml</beans: value> </beans: property> </beans: bean> <beans:bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close"> <beans:property name="forceShutdown" value="true" /> <beans:property name="startupTransactionService" value="true" /> </beans:bean> <beans:bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> <beans:property name="transactionTimeout"> <beans:value>300</beans:value> </beans:property> </beans:bean> <beans:bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <beans:property name="transactionManager"> <beans:ref bean="atomikosTransactionManager" /> </beans:property> <beans:property name="userTransaction"> <beans:ref bean="atomikosUserTransaction" /> </beans:property> </beans:bean> </beans: beans>
在我的daoconfig.xml中,我给出了persistence.xml的路径,这是我的persistence.xml文件
<?xml version="1.0" encoding="UTF-8"?> <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_1_0.xsd" version="1.0"> <persistence-unit name="payhub" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <mapping-file>META-INF/orm.xml</mapping-file> <class>com.evolvus.common.model.TaUser</class> ---------- ---------- ---------- <class>com.evolvus.common.model.TaBooks</class> </persistence-unit> </persistence>
在这里,我指定我的orm映射文件名称 orm.xml文件是
<?xml version="1.0" encoding="UTF-8" ?> <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0"> <description>Welcome</description> <package>com.evolvus.common.model</package> <!-- TaUser starts--> <entity class="com.evolvus.common.model.TaUser" name="TaUser"> <table name="ta_user" /> <attributes> <id name="userId"> <column name="USER_ID"/> <generated-value strategy="TABLE" /> </id> <basic name="userName"> <column name="USER_NAME" length="50" /> </basic> <basic name="password"> <column name="PASS_WORD" length="50" /> </basic> </attributes> </entity> <entity class="com.evolvus.common.model.TaBooks" name="TaBooks"> <table name="ta_user"/> <attributes> -------------- -------------- ------------ </attributes> </entity> </entity-mappings>
当我尝试运行服务器时,出现错误
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaTemplate' defined in ServletContext resource [/WEB-INF/xaconfig/daoJPAConfig.xml]: Cannot resolve reference to bean 'entityManagerFactory' while setting bean property 'entityManagerFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/xaconfig/daoJPAConfig.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: payhub] Unable to build EntityManagerFactory at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1317 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/xaconfig/daoJPAConfig.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: payhub] Unable to build EntityManagerFactory at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1412) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) Caused by: javax.persistence.PersistenceException: [PersistenceUnit: payhub] Unable to build EntityManagerFactory at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677) at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:132) Caused by: org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:329) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1300) ... 42 more
给我任何建议
首先,您要创建一个Hibernate SessionFactory和一个JPA EntityManagerFactory。除非您进行了非常奇怪的设置,否则这没有多大意义,并且您很可能应该放弃SessionFactory配置。您可以配置普通香草Hibernate,也可以配置JPA,而无需两者。
实体管理器工厂的创建失败,因为您将其指定JTA为事务类型,但是未定义JTA事务管理器查找类。(您在Hibernate SessionFactory配置中定义了它,但没有在JPA配置中定义它。)
JTA
将此添加到您的persistence.xml:
persistence.xml
<persistence-unit name="payhub" transaction-type="JTA"> ... <properties> <property name="hibernate.transaction.manager_lookup_class" value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup"/> </properties> </persistence-unit>