Spring3 + JPA2 + Java EE6 App Server =配置混乱
我的應(yīng)用程序要求非常簡單:使用Spring3.1和JPA2(休眠)開發(fā)幾個(gè)基于SOAP的Web服務(wù),并將其托管在JBoss AS 7.1上。
因此,我開始創(chuàng)建一個(gè)多模塊maven項(xiàng)目,其中一個(gè)jar模塊包含使用Spring&JPA的服務(wù)實(shí)現(xiàn),另一個(gè)war模塊將該服務(wù)公開為基于SOAP的Web服務(wù)。 但是關(guān)鍵部分是服務(wù)需要針對某些服務(wù)方法與多個(gè)數(shù)據(jù)庫進(jìn)行對話。
我知道從Spring獲得的JPA2集成支持,但沒有persistence.xml和很酷的packagesToScan屬性,這使工作變得更輕松。 我配置了2個(gè)數(shù)據(jù)源,2個(gè)LocalContainerEntityManagerFactoryBeans,注冊了2個(gè)JpaTransactionManagers并啟用了基于注釋的事務(wù)管理支持。
<tx:annotation-driven transaction-manager='txnManager1'/><tx:annotation-driven transaction-manager='txnManager2'/><bean class='org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor'/><bean class='org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor'/><!-- This will throw error because it found multiple EntityManagerFactory beans --><bean id='txnManager1' class='org.springframework.orm.jpa.JpaTransactionManager'p:entityManagerFactory-ref='emf1'/><bean id='txnManager2' class='org.springframework.orm.jpa.JpaTransactionManager'p:entityManagerFactory-ref='emf2'/> <bean id='emf1' class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'><property name='persistenceUnitName' value='Sivalabs1PU'></property> <property name='dataSource' ref='dataSource1'></property><property name='jpaVendorAdapter'><bean id='jpaAdapter' class='org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter'p:showSql='${hibernate.show_sql}'/></property><property name='jpaProperties'><props><prop key='hibernate.dialect'>${hibernate.dialect}</prop><prop key='hibernate.hbm2ddl.auto'>${hibernate.hbm2ddl.auto}</prop></props></property><property name='packagesToScan' value='com.sivalabs.springdemo.entities'></property><property name='loadTimeWeaver'><bean class='org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver'/></property></bean> <bean id='emf2' class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'><property name='persistenceUnitName' value='Sivalabs2PU'></property><property name='dataSource' ref='dataSource2'></property><property name='jpaVendorAdapter'><bean id='jpaAdapter' class='org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter'p:showSql='${hibernate.show_sql}'/></property><property name='jpaProperties'><props><prop key='hibernate.dialect'>${hibernate.dialect}</prop><prop key='hibernate.hbm2ddl.auto'>${hibernate.hbm2ddl.auto}</prop></props></property><property name='packagesToScan' value='com.sivalabs.springdemo.entities'></property><property name='loadTimeWeaver'><bean class='org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver'/></property></bean> <bean id='dataSource1' class='org.apache.commons.dbcp.BasicDataSource'><property name='driverClassName' value='${node1.jdbc.driverClassName}'></property><property name='url' value='${node1.jdbc.url}'></property><property name='username' value='${node1.jdbc.username}'></property><property name='password' value='${node1.jdbc.password}'></property></bean><bean id='dataSource2' class='org.apache.commons.dbcp.BasicDataSource'><property name='driverClassName' value='${node2.jdbc.driverClassName}'></property><property name='url' value='${node2.jdbc.url}'></property><property name='username' value='${node2.jdbc.username}'></property><property name='password' value='${node2.jdbc.password}'></property></bean>此后,我意識(shí)到將Entitymanager與正確的PersistenceUnit綁定,我需要將persistenceUnitName賦予LocalContainerEntityManagerFactoryBean。
<bean class='org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor'><property name='persistenceUnits' ><map><entry key='unit1' value='Sivalabs1PU'/><entry key='unit2' value='Sivalabs2PU'/></map></property></bean><bean id='emf1' class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'><property name='persistenceUnitName' value='Sivalabs1PU'></property><property name='dataSource' ref='dataSource1'></property>........ </bean> <bean id='emf2' class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'><property name='persistenceUnitName' value='Sivalabs2PU'></property><property name='dataSource' ref='dataSource2'></property>........ </bean>然后在我的Service Bean中,將EntityManager和事務(wù)管理器粘合在一起,如下所示:
@Service public class AdminUserService implements UserService {@PersistenceContext(unitName='Sivalabs1PU')private EntityManager sivalabs1EM;@PersistenceContext(unitName='Sivalabs2PU')private EntityManager sivalabs2EM;@Override@Transactional('txnManager1')public List<User> getAllUsersFromSivalabs1DB() {return sivalabs1EM.createQuery('from User', User.class).getResultList();}@Override@Transactional('txnManager2')public List<User> getAllUsersFromSivalabs2DB() {return sivalabs2EM.createQuery('from User', User.class).getResultList();}}現(xiàn)在,通過此設(shè)置,我得到了異常提示“找不到名稱為'Sivalabs1PU'的持久性單元”。 然后,在進(jìn)行一些谷歌搜索之后,我創(chuàng)建了META-INF / persistence.xml文件,如下所示:
<persistence><persistence-unit name='Sivalabs1PU' transaction-type='RESOURCE_LOCAL'> </persistence-unit><persistence-unit name='Sivalabs2PU' transaction-type='RESOURCE_LOCAL'> </persistence-unit></persistence>現(xiàn)在,持久性單元名稱錯(cuò)誤得到解決,并出現(xiàn)其他異常,說明“未從[用戶]映射用戶”。 User類使用@Entity注釋,并且位于“ com.sivalabs.springdemo.entities ”包中,我將其配置為“ packagesToScan ”屬性。 我不明白為什么'packagesToScan'屬性不起作用,如果沒有persistence.xml,它會(huì)很好地工作。 所以暫時(shí)我在persistence.xml文件中配置了實(shí)體類。
<persistence><persistence-unit name='Sivalabs1PU' transaction-type='RESOURCE_LOCAL'> <class>com.sivalabs.springdemo.entities.User</class> </persistence-unit><persistence-unit name='Sivalabs2PU' transaction-type='RESOURCE_LOCAL'> <class>com.sivalabs.springdemo.entities.User</class></persistence-unit></persistence>最終,當(dāng)我運(yùn)行調(diào)用AdminUserService方法的JUnit測試時(shí),一切看起來都很好并且工作正常。 然后,我在JBoss AS 7.1服務(wù)器上部署了war文件,然后再次出現(xiàn)了很多錯(cuò)誤。 JBoss抱怨“當(dāng)未設(shè)置“ hibernate.dialect”時(shí),Connection不能為空”。 '[PersistenceUnit:Sivalabs1PU]無法建立EntityManagerFactory。
經(jīng)過幾分鐘的思考,我了解到JBoss服務(wù)器正在嘗試執(zhí)行“配置約定”規(guī)則應(yīng)做的事情。 JBoss試圖創(chuàng)建EntityManagerFactory,因?yàn)樗陬惵窂街姓业搅薓ETA-INF / persistence.xml。 但是由于它不包含jdbc連接細(xì)節(jié),因此引發(fā)了Error。
再次谷歌搜索之后,我發(fā)現(xiàn)我們可以將persistence.xml重命名為其他名稱(spring-persistence.xml),并使用Spring將此新名稱連接起來,如下所示:
<bean id='emf1' class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'><property name='persistenceUnitName' value='Sivalabs1PU'></property><property name='persistenceXmlLocation' value='classpath:META-INF/spring-persistence.xml'/><property name='dataSource' ref='dataSource1'></property>........ </bean> <bean id='emf2' class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'><property name='persistenceUnitName' value='Sivalabs2PU'></property><property name='persistenceXmlLocation' value='classpath:META-INF/spring-persistence.xml'/><property name='dataSource' ref='dataSource2'></property>........ </bean>最終,我成功地使該應(yīng)用程序在JBoss AS 7.1上運(yùn)行(仍然不知道還有多少其他漏洞)。
但是在這里我不了解Spring的一些概念:
1.當(dāng)我嘗試提供persistenceUnitName時(shí),為什么Spring正在檢查該名稱是否存在于persistence.xml中? 無論如何,persistence.xml不含任何單元名稱!
2.為什么在與persistence.xml一起使用時(shí)packagesToScan機(jī)制失敗? 是彈簧蟲嗎?
一切似乎都正常,只是缺少一件事,在我與Spring和Tomcat一起工作時(shí)通常會(huì)露出微笑:-(
我非常喜歡Spring框架,自2006年以來一直在使用它,在編寫Spring代碼的同時(shí)我非常喜歡。 這并不意味著我不喜歡CDI,EJB3,JAX-RS :-)
無論如何,通過以上所有練習(xí),我感覺就像Spring3 + JPA2 + JavaEE6AppServer = Confusion Over Configuration ,這只是我(一個(gè)普通的Java開發(fā)人員)的意見。
再說一次:Spring很棒,JavaEE6很棒,最新的JavaEE6 Application服務(wù)器也很棒:-)。
參考: Spring3 + JPA2 + JavaEE6AppServer =來自我們的JCG合作伙伴 Siva Reddy的“配置混亂”,來自My Experiments on Technology博客。
翻譯自: https://www.javacodegeeks.com/2012/10/spring3-jpa2-java-ee6-app-server.html
總結(jié)
以上是生活随笔為你收集整理的Spring3 + JPA2 + Java EE6 App Server =配置混乱的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北京市公租房备案编号(租房备案编号)
- 下一篇: ddos攻击可以报警吗(ddos攻击报警