I was struck , please help on this. My life is happy(Everything is working) when I was using 6 and WebSphere 7.5, but now, we have to migrate to Java 7, WebSphere 8.5.5.12.
My requirement is like, same DB for 3 countries with different schema, all beans are same for 3 countries, but when I am trying to get persistence unit for SG, it is returning default HK one.
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="MY_HK">
<property name="persistenceUnitName" value="MyProjHK" />
<property name="dataSource" ref="dataSource"></property>
<property name="jpaVendorAdapter" ref="openJpaVendorAdapter" />
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="MY_IN">
<property name="persistenceUnitName" value="MyProjIN" />
<property name="dataSource" ref="dataSource"></property>
<property name="jpaVendorAdapter" ref="openJpaVendorAdapter" />
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistenceIN.xml"></property>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="MY_SG">
<property name="persistenceUnitName" value="MyProjSG" />
<property name="dataSource" ref="dataSource"></property>
<property name="jpaVendorAdapter" ref="openJpaVendorAdapter" />
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistenceSG.xml"></property>
</bean>
Related
I'm working on spring boot application, which already has a database connection established in its applicationContext.xml file and the necessary transaction manager and vendors etc.
I now need to connect the app to a second database. But I'm having issues with this. In my unit tests the connection is fine and can make simple queries to retrieve data, which is all I need it to do. However when I compile the app into a jar and run it, I get the following error
NoUniqueBeanDefinitionException: No qualifying bean of type "org.springframework.transaction.PlatformTransactionManager" available: expected single matching bean but found 2: transactionManager, transactionManager2
I have spent ages looking up how to solve this, and the suggested fixes I have found here , here and here have not worked.
I have one persistence.xml with two persistence units defined. And in my applicaitonContext.xml I defined two datasources, two transaction managers and two entity Manager Factories. I then use the #persitsencecontext and #Transactional("") annotations to say which persistence unit and managers to use, but I still get an error. I also added in the <qualifier> tag to the app context file, as I saw this as a suggested fix with the #transactional annotation, still no luck.
My code is below, can anyone spot an errors I have made, and why it may not be working as expected
applicationContext.xml
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="..."/>
<property name="username" value="..."/>
<property name="password" value="..."/>
</bean>
<bean id="entityManagerFactory" name="proxy">
<property name="persistenceUnitName" value="proxy" />
<property name="persistenceUnitXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="dataSource" ref="dataSource1" />
<property name="jpaVendorAdapter" ref="hiberanteVendorAdapter" />
<property name="jpaProperties">
<props>
<prop key="hiberante.hbm2ddl.auto">valudate</prop>
</props>
</property>
</bean>
<bean id="hibernateVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />
<property name="database" value="HSQL" />
<property name="showSql" value="true" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<qualifier value="transactionManager1" />
</bean>
<!-- Second datasource -->
<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="..."/>
<property name="username" value="..."/>
<property name="password" value="..."/>
</bean>
<bean id="entityManagerFactory2" name="proxy">
<property name="persistenceUnitName" value="proxy2" />
<property name="persistenceUnitXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="dataSource" ref="dataSource2" />
<property name="jpaVendorAdapter" ref="hiberanteVendorAdapter2" />
<property name="jpaProperties">
<props>
<prop key="hiberante.hbm2ddl.auto">valudate</prop>
</props>
</property>
</bean>
<bean id="transactionManager2" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory2" />
<qualifier value="transactionManager2" />
</bean>
<bean id="hibernateVendorAdapter2" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
<tx:annotation-driven/>
Implementation
#Repository
#Transactional("transactionManager2")
public class myDaoImpl extends GenericJPADao<Integer, Integer> implements ImyDao {
#PersistenceContext(unitName="proxy2")
protected EntityManager em;
}
SOLUTION
The accepted answer was the correct solution for me, but a few things to note. The beans have to point to their respective entityManagerFactory's and you need to be careful on which bean you set the autowire-candidate="false" on, as I set it on the incorrect one at first, and had transactions rolled back as a result. I think there could be cleaner solution to this, but as a quick fix it works fine
try this :
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" autowire-candidate="false">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="transactionManager2" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
I need to configure xml file for DAO. So in my xml file, I have declared two entityManager Factory and I want to set one of them as default persistence unit. I have declared that part as below in my dao.xml
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor">
property name="defaultPersistenceUnitName" value="pumps-jpa"/>
</bean>
But, it didn't not work for me, it was not taking default persistence unit. I was getting error like this
No unique bean of type is defined: expected single bean but found 2:
After lot of searching, I found one code snippet in which they have mentioned bean id as spring class name i.e. org.springframework.context.annotation.internalPersistenceAnnotationProcessor, as shown below
<bean id="org.springframework.context.annotation.internalPersistenceAnnotationProcessor"
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor">
property name="defaultPersistenceUnitName" value="pumps-jpa"/>
</bean>
So, after mentioning this bean id, it is taking default persistence unit name. I want to know, why do I need to mention spring class (org.springframework.context.annotation.internalPersistenceAnnotationProcessor) as bean id? Is it a kind of hack or something?
Whole dao.xml is declared below
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:${catalina.base}/conf/pumps-dbconfig.properties"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass">
<value>${jdbc.driver}</value>
</property>
<property name="jdbcUrl">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.user}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
<property name="initialPoolSize"><value>10</value></property>
<property name="minPoolSize"><value>10</value></property>
<property name="maxPoolSize"><value>${jdbc.maxConnections}</value></property>
<property name="maxIdleTimeExcessConnections"><value>600</value></property>
<!-- <property name="timeout"><value>0</value></property> --> <!-- 0 means: no timeout -->
<property name="idleConnectionTestPeriod"><value>60</value></property>
<property name="acquireIncrement"><value>5</value></property>
<property name="maxStatements"><value>0</value></property> <!-- 0 means: statement caching is turned off. -->
<property name="numHelperThreads"><value>3</value></property> <!-- 3 is default -->
<property name="unreturnedConnectionTimeout"><value>0</value></property>
<property name="debugUnreturnedConnectionStackTraces"><value>true</value></property>
<property name="testConnectionOnCheckout"><value>true</value></property>
</bean>
<!--
Configuration for Hibernate/JPA
-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="pumps-jpa" />
<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="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
<!-- DEFAULT PERSISTENCE UNIT DECLARATION -->
<bean id="org.springframework.context.annotation.internalPersistenceAnnotationProcessor"
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor">
<property name="defaultPersistenceUnitName" value="pumps-jpa"/>
</bean>
<bean id="r-dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass">
<value>${r-jdbc.driver}</value>
</property>
<property name="jdbcUrl">
<value>${r-jdbc.url}</value>
</property>
<property name="user">
<value>${r-jdbc.user}</value>
</property>
<property name="password">
<value>${r-jdbc.password}</value>
</property>
<property name="initialPoolSize"><value>10</value></property>
<property name="minPoolSize"><value>10</value></property>
<property name="maxPoolSize"><value>${r-jdbc.maxConnections}</value></property>
<!-- <property name="timeout"><value>0</value></property> --> <!-- 0 means: no timeout -->
<property name="maxIdleTimeExcessConnections"><value>600</value></property>
<property name="idleConnectionTestPeriod"><value>60</value></property>
<property name="acquireIncrement"><value>5</value></property>
<property name="maxStatements"><value>0</value></property> <!-- 0 means: statement caching is turned off. -->
<property name="numHelperThreads"><value>3</value></property> <!-- 3 is default -->
<property name="acquireRetryAttempts"><value>3</value></property>
<property name="testConnectionOnCheckout"><value>true</value></property>
</bean>
<!--
Configuration for Hibernate/JPA
-->
<bean id="r-entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="pumps-jpa" />
<property name="dataSource" ref="r-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="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
<bean id="BaseDataConnection" class="com.myntra.commons.dao.impl.BaseDataConnection">
<property name="roEntityManagerFactory" ref="r-entityManagerFactory" />
</bean>
I think your original problem was not what you meant! By configuration you can refer to one of your Entity Manager's existing Persistence Unit implementations as 'the default persistence unit'! You can do this in your XML config! persistence.xml in JPA is your persistence config your beans (configuration) xml is an other option to point to some of the defined persistence units. Please post your whole config xml ...
For the rest of your problem with the Bean ID:
There is already a Bean in your container initialised with the same name.
The Container is using the Bean Id as a unique Id of your identifiable code fragment! If you use another name then your container will initialise another bean instance of the same class and give it the other name. However as I pointed out above this is not related to your problem! (Even if you can bypass your existing bean implementations and redefine your config if you do not have other options!)
This question already has answers here:
Spring Boot, Spring Data JPA with multiple DataSources
(6 answers)
Closed 4 years ago.
I read all the related questions and tried all of them but still can't make my configuration straight.
I've two databases and i want to use them as datasources in my application.
Here is my context file:
<jee:jndi-lookup id="firstDataSource" jndi-name="java:/comp/env/jdbc/firstDS" expected-type="javax.sql.DataSource" />
<jee:jndi-lookup id="secondDataSource" jndi-name="java:/comp/env/jdbc/secondDS" expected-type="javax.sql.DataSource" />
<bean name="persistenceProvider" class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="thisEntityManagerFactory">
<property name="dataSource" ref="firstDataSource"/>
<property name="packagesToScan" value="com.a.b.first.model"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="showSql" value="true"/>
<property name="databasePlatform" value= "org.hibernate.dialect.Oracle10gDialect"/>
<property name="database" value="ORACLE"/>
</bean>
</property>
<property name="persistenceUnitName" value="firstPersistenceUnit" />
<property name="persistenceProvider" ref="persistenceProvider"></property>
<property name="jpaProperties">
<value>
hibernate.generate_statistics = true
hibernate.cache.use_second_level_cache = true
hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
hibernate.cache.use_query_cache = true
<!--hibernate.hbm2ddl.auto=create-->
</value>
</property>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="otherEntityManagerFactory">
<property name="dataSource" ref="secondDataSource"/>
<property name="packagesToScan" value="com.a.b.second.model"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="showSql" value="true"/>
<property name="databasePlatform" value= "org.hibernate.dialect.Oracle10gDialect"/>
<property name="database" value="ORACLE"/>
</bean>
</property>
<property name="persistenceUnitName" value="secondPersistenceUnit" />
<property name="persistenceProvider" ref="persistenceProvider"></property>
<property name="jpaProperties">
<value>
hibernate.generate_statistics = true
hibernate.cache.use_second_level_cache = true
hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
hibernate.cache.use_query_cache = true
<!--hibernate.hbm2ddl.auto=create-->
</value>
</property>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="thisTransactionManager">
<property name="entityManagerFactory" ref="thisEntityManagerFactory"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="otherTransactionManager">
<property name="entityManagerFactory" ref="otherEntityManagerFactory"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<tx:annotation-driven transaction-manager="thisTransactionManager" />
<tx:annotation-driven transaction-manager="otherTransactionManager" />
<jpa:repositories base-package="com.a.b.first.intf" entity-manager-factory-ref="thisEntityManagerFactory" transaction-manager-ref="transactionManager"/>
<jpa:repositories base-package="com.a.b.second.intf" entity-manager-factory-ref="otherEntityManagerFactory" transaction-manager-ref="otherTransactionManager" />
Problem is when i try to use a repository interface which is located under package com.a.b.second.intf, it goes to firstDataSource and throws a SQLSyntaxErrorException with message "ORA-00942: table or view does not exist". Because there is no such table in the first database.
There is a line in tho logs for each EntityManagerFactory, saying
Building JPA container EntityManagerFactory for persistence unit
'default'
And in the next line it prints PersistenceUnitInfo for this EntityManagerFactory. The "Non JTA datasource" property of the PersistenceUnitInfo is same for both EntityManagerFactories. I guess that means both persistence units uses the same datasource.
What am i missing?
Thanks.
In your service layer you should have something like this:
#Service
#Transactional("thisTransactionManager")
public class ThisService{
#Autowired
private com.a.b.first.intf.Repo1 repo1;
}
#Service
#Transactional("otherEntityManagerFactory")
public class OtherService{
#Autowired
private com.a.b.second.intf.Repo1 repo1;
}
This way, when you call a service method, the TransactionInterceptor can load the appropriate transaction manager, associated to the EntityManagerFactory you want to operate with.
i've got a spring maven project with javamelody.
I use hibernate with spring, don't have any JNDI data scource.
the datasource in xml conf:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://${database.location}:${database.port}/${database.dbname}?zeroDateTimeBehavior=convertToNull&characterEncoding=utf8"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="persistenceUnitName" value="rtt-backend" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="database" value="MYSQL" />
<property name="showSql" value="false" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
but if i connect to javamelody monitor page says:
"sql Statistics sql - 1 day -None"
I tried :
in presistence.xml :
net.bull.javamelody.JpaPersistence
use wrapper for data source
<bean id="wrappedDataSource" class="net.bull.javamelody.SpringDataSourceFactoryBean">
<property name="targetName" value="dataSource" /> </bean>
But still nothing.
As said in the user guide, simply add in your spring context configuration:
classpath:net/bull/javamelody/monitoring-spring.xml
Or if you want to use
<bean id="wrappedDataSource" class="net.bull.javamelody.SpringDataSourceFactoryBean">
<property name="targetName" value="dataSource" />
</bean>
then replace in your entityManagerFactory and transactionManager
<property name="dataSource" ref="dataSource" />
with
<property name="dataSource" ref="wrappedDataSource" />
I'm failling to use Spring4 togather with Hibernate4 in a standalone process (no container like tomcat, WAS, ...)
How can I use Hibernate4, Spring4 and Spring data repositories togather in a standalone process?
However I confiugre Spring I allways get the same exception:
Caused by: java.lang.NullPointerException
at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:76)
at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:118)
at org.hibernate.engine.transaction.internal.jta.CMTTransaction.join(CMTTransaction.java:149)
When googling for this, I get pointet to some information about hibernate.transaction.jta.platform and the docu for Hibernate 4.3 is here http://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html_single/#services-JtaPlatform
But the only option I see for my case would be org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform but this still leads to the same error.
Here is my Spring config:
<context:component-scan base-package="com.xx.yy" />
<jpa:repositories base-package="com.xx.zz.respositories"></jpa:repositories>
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/culture" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jtaDataSource" ref="dataSource" />
<property name="packagesToScan" value="culture.matching.index.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="showSql" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
<property name="database" value="MYSQL" />
</bean>
</property>
<property name="jpaProperties">
<value>
hibernate.transaction.jta.platform=org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform
</value>
</property>
</bean>
Answer by #geoand helped a lot: https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-simple
I therefore moved from XML to Java config