It seems that JDBCTemplate ignores SET CONSTRAINT ALL DEFERRED - java

I am having this Spring 4.0 service that copies tables from one schema to another. I am switching between Datasources programmatically by updating the Datasource in an abstract class from which all DAOs inherit.
public abstract class GenericDao implements SystemChangedListener {
private static final Logger logger = Logger.getLogger(GenericDao.class);
private NamedParameterJdbcTemplate jdbcTemplate;
/**
* Initializing the bean with the definition data source through #Autowired
* #param definitionDataSource as instance of #DataSource
*/
#Autowired
private void setDataSource(DataSource definitionDataSource) {
this.jdbcTemplate = new NamedParameterJdbcTemplate(definitionDataSource);
}
public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(){
return this.jdbcTemplate;
}
#Override
public void updateDataSource(DataSource dataSource) {
this.setDataSource(dataSource);
}
Whenever I need to switch to anothe DataSource I call this method. It all works fine so far, except for the cases when I have a parent-child tables in a foreign key relationship with foreign key defined as deferrable. I get 'ORA-02292: integrity constraint - child record' found whenever the application tries to delete first the parent table.
This happens in a service by calling the methods like this:
logger.info("Switching to target system: " + repDTO.getSourceSystem());
systemService.switchSystem(targetSys);
logger.info("Cleaning up data in target table: " + repDTO.getTableToReplicate());
// deleting the data
managedTableService.cleanData(repDTO.getTableToReplicate());
logger.info("Importing data in target table: " + repDTO.getTableToReplicate());
// importing the data
managedTableService.importData(inserts);
Methods are executed in a transaction so when something goes wrong I return to the clean state. I also use Hibernate for collecting meta information about my tables, before copying them, but for this I use a different connection.
I tried to call SET CONSTRAINT ALL DEFERRED before the cleaning method, but it doesn't work. I even tried a batch update - SET CONSTRAINT ALL DEFERRED + DELETE FROM TABLE, still no success. What am I doing wrong? Any help is appreciated. Thank you!
PS. I use Oracle 11 as a DB. Here's my spring datasource configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<!-- Scans within the base package of the application for #Components to configure as beans -->
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:/db.properties" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:packagesToScan="de.telekom.cldb.admin"
p:dataSource-ref="dataSource"
p:jpaPropertyMap-ref="jpaPropertyMap"
p:jpaVendorAdapter-ref="hibernateVendor" />
<bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="${db.dialect}" />
</bean>
<!-- system 'definition' data source -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="${db.driver}"
p:url="${db.url}"
p:username="${db.username}"
p:password="${db.password}" />
<!--
p:maxActive="${dbcp.maxActive}"
p:maxIdle="${dbcp.maxIdle}"
p:maxWait="${dbcp.maxWait}"/>
-->
<util:map id="jpaPropertyMap">
<entry key="generateDdl" value="false"/>
<entry key="hibernate.hbm2ddl.auto" value="validate"/>
<entry key="hibernate.dialect" value="${db.dialect}"/>
<entry key="hibernate.default_schema" value="${db.schema}"/>
<entry key="hibernate.format_sql" value="false"/>
<entry key="hibernate.show_sql" value="true"/>
<entry key="hibernate.connection.SetBigStringTryClob" value="true"/>
<entry key="hibernate.c3p0.min_size" value="5" />
<entry key="hibernate.c3p0.max_size" value="20" />
<entry key="hibernate.c3p0.timeout" value="300" />
<entry key="hibernate.c3p0.max_statements" value="50" />
<entry key="hibernate.c3p0.idle_test_period" value="3000" />
</util:map>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
For switching between DataSources progammatically I use org.apache.commons.dbcp.BasicDataSource
######## UPDATE
Hibernate DEBUG log

Related

Spring mvc + hibernate/jpa -> entity manager is not injected despite #PersistenceContext

I have a problem with EntityManager. When I try to use EntityManager in a dao class, I got null pointer exception. So EntityManager is not injected despite #PersistenceContext annotation.
My dao:
package com.fido.pia.dao;
import com.fido.pia.model.User;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
#Repository
public class UserDao {
#PersistenceContext
protected EntityManager entityManager;
public User save(User row) {
if(row.isNew()) {
entityManager.persist(row);
return row;
} else {
return entityManager.merge(row);
}
}
}
Servlet Config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--
Adds some default beans (HandlerAdapter, HandlerMapping, Binding Initializer...). It also turn on some annotations.
Explanation in http://stackoverflow.com/questions/28851306/spring-framework-what-is-the-purpose-of-mvcannotation-driven
WITHOUT THIS, #RequestMapping ANNOTATIONS ARE LOADED, BUT MAPPING DO NOT WORK!!
-->
<mvc:annotation-driven />
<!-- Set loading annotations from classes
<context:component-scan base-package="com.fido.pia"/>-->
<!--manual homepage-->
<mvc:view-controller path="/" view-name="home"/>
<!--view resolver-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<!--static resources - request will be handeled by ResourceHttpRequestHandler-->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!--database config-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/pia" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<!--entity manager factory-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="com.fido.pia" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!--<property name="generateDdl" value="true" />-->
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<!-- Transactions -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!--Set loading annotations from classes-->
<context:component-scan base-package="com.fido.pia"/>
</beans>
Any ideas what is wrong here?
In entityManagerFactory bean definition, try this :
<property name="packagesToScan" value="com.fido.pia.*" />
This should work
I finally solve it. The problem was that I use common dependency injection to inject my dao class in controller. When I change it to DI with autowired (added #autowired to controller constructor), entity manager in dao is initialized.
So now it works, but I'm still curious about why is that change so important. I've asked new question about it.
You need to enable persistence annotations:
<context:annotation-config/>
or
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

JPA packagesToScan not causing package-info.java annotations to be scanned

I am having trouble configuring JPA global type mappings via the package-info.java file, which looks like this:
#TypeDefs({
#TypeDef(
typeClass = MyCustomUserType.class,
defaultForType = MyType.class
)
})
package my.entity.package;
import...
My spring configuration file looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:spring-configured />
<context:annotation-config />
<context:component-scan base-package="my.package"/>
<context:property-placeholder location="classpath:/my.properties" />
<bean id="testDataSource" class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="com.ibm.db2.jcc.DB2Driver"
p:url="jdbc:db2://${database.host}:50000/${database.dbname}:currentSchema=I0071DBA;"
p:username="${database.username}"
p:password="${database.password}"
p:initialSize="5"
p:maxActive="10">
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="testDataSource" />
<property name="persistenceProviderClass" value="org.hibernate.jpa.HibernatePersistenceProvider"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect"/>
<entry key="hibernate.default_schema" value="MySchema"/>
<entry key="hibernate.cache.use_query_cache" value="false"/>
<entry key="hibernate.cache.use_second_level_cache" value="false"/>
</map>
</property>
<property name="packagesToScan" value="my.entity.package"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
I believe the packagesToScan property is being used, because all my entity classes are configured into the EntityManagerFactory. Only the package-info.java file is not being used. Any suggestions for configuring the package-info.java file into the EntityManagerFactory?

Cannot inject sessionFactory

While trying to get sessionFactory.getCurrentSession() debugger shows that sessionFactory is null. I assume Spring 3 fails to inject sessionFactory into this class although all configuration seems to be in place. How to fix it?
ServiceOrderDAO:
#Transactional
public class ServiceOrderDAO{
#Autowired
static
SessionFactory sessionFactory;
public static List<ServiceOrderEntity> search(params...){
Session localSession = sessionFactory.getCurrentSession();
...
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:annotation-config />
<mvc:annotation-driven/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="" />
<property name="suffix" value=".jsp" />
</bean>
<context:component-scan base-package="controller" />
<context:component-scan base-package="dao" />
<context:component-scan base-package="service" />
<context:property-placeholder location="classpath:dbConnection.properties" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="model" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!--<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.pass}" />
</bean>
<bean id="jdbcTemplateBean" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
There are a few things I think you'll want to touch up:
SessionFactory shouldn't be static, nor should your search method be static if you're trying to treat that class as a Spring bean.
Add a #Component or #Repository annotation to the class. I don't think Spring will autowire classes that are missing a stereotype annotation on the class.
You should consider moving your #Transactional annotation to the method so you can provide more fine-grained propagation. For example, your search method may not require a transaction so you may want to use #Transactional(propagation = Propagation.SUPPORTS). Check out the Spring documentation for additional info that explains the various annotations and where/how to annotate transactions.
sessionFactory being static definitely is the cause of the problem. You can't inject static fields with spring.
Going under the covers, the static fields gets initialized by classloader, before the constructor gets called, and therefore before spring gets chance to inject anything.
And your service class should be transactional, not your dao. And yes you need to annotate with #Component or #Service or similar.

Spring bean configuration list<map>

Im trying to create a bean configuration file for my
SettingsDto class:
public class SettingsDto {
private String administratorEmail;
private String gatekeeperAddress;
private String webRtcUrl;
private String userGuideUrl;
private String vmrFaqUrl;
private String lyncGuideUrl;
List<Map<String, String>> supportPhones;
List<String> audioCalls;
But Im having issues with how Im doing the supportPhones (List<Map<String, String>>)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<context:component-scan base-package="sandbox.spring" />
<bean id="SettingsBean" class="com.dto.SettingsDto">
<property name="administratorEmail" value="v#.com" />
<property name="gatekeeperAddress" value="192.168.1.0" />
<property name="webRtcUrl" value="https://web.com" />
<property name="userGuideUrl"
value="url" />
<property name="vmrFaqUrl"
value="url" />
<property name="lyncGuideUrl"
value="url" />
<property name="audioCalls">
<util:list>
<value>+1 (000)000-0000</value>
<value>(000)000-0000</value>
</util:list>
</property>
<property name="supportPhones">
<util:list>
<ref bean="supportPhonesMapping1" />
<ref bean="supportPhonesMapping2" />
</util:list>
</property>
<util:map id="supportPhonesMapping1">
<entry key="name" value="North America" />
<entry key="phone" value-ref="+1 111-1111" />
</util:map>
<util:map id="supportPhonesMapping2">
<entry key="name" value="+11 111-1111" />
<entry key="phone" value-ref="International" />
</util:map>
</bean>
</beans>
The error I get is
Invalid content was found starting with element 'util:map'. No child
element is expected at this point
You cannot set value to util:map that way. value can only take a string. Define a util:map separately, then use ref to reference it.
For example:
<util:map id="myMap">
<entry key="name" value="..." />
</util:map>
<util:list>
<ref bean="myMap"/>
</util:list>
Also, value-ref should reference another bean - currently you have it as a string literal value, which you can simply use value for.
Maybe it's your beans schema. You have it slightly wrong. It should be:
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
so in the end there were a few issues.
first off my declaration was wrong
<entry key="phone" value-ref="International" />
needed to be
<entry key="phone" value="International" />
(no "-ref")
I also changed the xml to define my list and map outside of the bean then referenced it in the bean
<property name="supportPhones" ref="supportPhoneList" />

Insert into two tables in two different database

My Java web application on spring framework is using two database say database-1 and database-2. Both database have User table. What I am trying to do is to insert record into both tables at same time.
There are two persistence-unit in the persistence.xml that is pointing out to database.
Here is my 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="p1-jpa" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/MySqlDS2</jta-data-source>
<class>com.xyz.entity.User</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
</properties>
</persistence-unit>
<persistence-unit name="p2-jpa" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/MySqlDS2</jta-data-source>
<class>com.mmxhealthcare.entity.MMASCUser</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" />
</properties>
</persistence-unit>
</persistence>
Now Whenever I am trying to add user, it is inserted only in Database-1. I am not getting any exception.
Here is my spring-servlet.xml file:-
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util" xmlns:security="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="0"/>
</bean>
<!-- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean> -->
<context:property-placeholder location="classpath:config.properties" />
<context:annotation-config />
<context:component-scan base-package="com.xyz.controller" />
<context:component-scan base-package="com.xyz.service" />
<context:component-scan base-package="com.xyz.dao" />
<context:component-scan base-package="com.xyz.security" />
<context:component-scan base-package="com.xyz.dto" />
<context:component-scan base-package="com.xyz.util" />
<context:component-scan base-package="com.xyz.entity" />
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="transactionManager1" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="aaentityManagerFactory" />
</bean>
<bean id="transactionManager2" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="mmascentityManagerFactory" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="d1SourceLocal" />
<property name="persistenceUnitName" value="p1-jpa" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="mmascentityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="d2DataSourceLocal" />
<property name="persistenceUnitName" value="p2-jpa" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<!-- <bean id="dataSourceLocal" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/MySqlDS2"/>
</bean> -->
<!-- Local -->
<bean id="d1SourceLocal"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="d2DataSourceLocal"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${d2-database.driver}" />
<property name="url" value="${d2-database.url}" />
<property name="username" value="${d2-database.username}" />
<property name="password" value="${d2-database.password}" />
</bean>
</beans>
Here it is my service class:
public class Userservice{
#Autowired
Database2IUserDAO immDao;
#Autowired
Database1IUserDAO iaaDao;
public User saveUser(fname,address){
User u = new User(); // This points Database-1 User table.
u.setFname(fname);
u.setAddress(address);
iaaDao.save(u);
User2 u2 = new User2(); // This points Database-2 User table.
u2.setFname(fname);
u2.setAddress(address);
immDao.save(u2);
}
}
Here is my Database1IUserDAO //This is an Interface
package com.xyz.dao;
public interface Database1IUserDAO {
public Object save(Object ob);
}
Here is my Database2IUserDAO //This is an another Interface for database2
package com.xyz.dao;
public interface Database2IUserDAO {
public Object save(Object ob);
}
** And this is finally DAO class for Database-1 and Database 2**
My both DAO class extends BaseDao class, that have Save() method that we are using to insert or save.
BaseDao.java
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.transaction.annotation.Transactional;
public class BaseDAO {
protected EntityManager entityManager;
#PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this. entityManager = entityManager;
}
#Transactional
public Object save(Object ob) {
Object object = entityManager.merge(ob);
return object;
}
#Transactional
public void remove(Object ob) {
Object object = entityManager.merge(ob);
entityManager.remove(object);
}
#Transactional
public int update(String query) {
return entityManager.createQuery(query).executeUpdate();
}
}
Please help.
You have to use database specific Transaction Manager as you mentioned in your spring-context.xml file as below.
<bean id="transactionManager2" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="mmascentityManagerFactory" />
</bean>
You should create a save function in your DAO Class with database specific Transaction Manager as follows:
#Transactional(value="transactionManager2")
public Object save(Object ob) {
Object object = entityManager.merge(ob);
return object;
}
I hope it will work for you.
You seem to be using the same EntityManager (EM) from the BaseDAO for all your DAOs. Since you don't specify which TransactionManager the EM is using, it will default to this one:
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
... as noted in the documentation http://docs.spring.io/spring/docs/2.0.8/reference/transaction.html (find table 9.2)
If you want to write to another database, you will need to explicity tell Spring which one you want to use. See this answer as an example:
Spring multiple #Transactional datasources
It looks you are using the same datasource for both the persistence unit.
ie java:jboss/datasources/MySqlDS2
so it is inserting into only one DB which is corresponding to above data source mstly Mysql DB.
so add different datasource in both the persistence-unit , and that should help you to insert to both the databases.
it wont give any exception because one datasource that you are using might be valid datasource(i cant guarantee as we dont have data source information in your post).
let me know for any thing else.

Categories