All. Attached herewith all the files. If I give the same name for both bean property name and reference, it returns the object. But it returns null, in case both are different. Please help. Thank you so much.
The AuthenticateAction.java file has got the detailed comments inside it.....
below are my files list:
WIRAdminBaseAction.java ---> my base action
AuthenticateAction.java ---> my java file that calls the bean here
applicationContext_MNC.xml
The below way of calling works...... This is not encouraged, as we
should not use applicationContext always
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletRequest().getSession().getServletConte xt());
ICacheDelegate cacheAction = (ICacheDelegate)applicationContext.getBean("BMOCacheDelegate");
The below way of calling does NOT work .... returns null value....
Please help... I assume that, since I have extended the
WIRAdminBaseAction, i should be able to call the getCacheDelegate
directly and it should return my cacheDelegate object ... Again,
Please note.....if I change my applicationContext_MNC.xml as below,
the below way of calling works fine. But, i don't want to change my
applicationContext_MNC.xml as below, due to some necessity.
<bean id="BMOWIRAdminBaseAction" class="com.symcor.wiradmin.web.action.WIRAdminBase Action">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
<bean id="cacheDelegate" class="com.symcor.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="BMOStatusDBDAO" /></property>
</bean>
Is it that the name and bean should have the same value.... ??? No
Need to be.....Am i right ? Please advise.
getCacheDelegate().getActorAction(1); // this way of calling doesn't work and returns null value. please help.
MY CODE Follows below.
AuthenticateAction.java
package com.symcor.wiradmin.web.action;
import java.net.UnknownHostException;
import java.sql.SQLException;
import org.bouncycastle.crypto.CryptoException;
import org.springframework.context.ApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.web.context.support.WebApplica tionContextUtils;
import com.symcor.wiradmin.delegate.ICacheDelegate;
public class AuthenticateAction extends WIRAdminBaseAction {
private static final long serialVersionUID = 1L;
public String authenticate() throws UnknownHostException, CryptoException,
DataAccessException, SQLException{
/** This way of calling works...... This is not encouraged, as we should not use applicationContext always **/
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContex t(getServletRequest().getSession().getServletConte xt());
ICacheDelegate cacheAction = (ICacheDelegate) applicationContext.getBean("BMOCacheDelegate");
/** The below way of calling does NOT work .... returns null value.... Please help...
* I assume that, since I have extended the WIRAdminBaseAction, i should be able to call the getCacheDelegate directly
* and it should return my cacheDelegate object ...
* Again, Please note.....if I change my applicationContext_MNC.xml as below, the below way of calling works fine...
* but, i don't want to change my applicationContext_MNC.xml as below, due to some necessity.
<bean id="BMOWIRAdminBaseAction" class="com.symcor.wiradmin.web.action.WIRAdminBase Action">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
<bean id="cacheDelegate" class="com.symcor.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="BMOStatusDBDAO" /></property>
</bean>
... is it that the name and bean should have the same value.... ??? No Need to be.....Am i right ? Please advise.
*
* **/
getCacheDelegate().getActorAction(1); // this way of calling doesn't work and returns null value. please help.
return "success";
}
}
WIRAdminBaseAction.java
package com.symcor.wiradmin.web.action;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.config.entities.Parameteri zable;
import com.symcor.wiradmin.delegate.ICacheDelegate;
public class WIRAdminBaseAction extends ActionSupport implements Preparable, ParameterAware, Parameterizable, SessionAware,RequestAware {
private HttpServletRequest request;
private static final long serialVersionUID = 1L;
private HttpServletResponse response;
private ICacheDelegate cacheDelegate;
private Map session;
private Map<String, String> params;
private Map parameters;
public void prepare() throws Exception {
}
public String execute() throws Exception {
return SUCCESS;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public HttpServletRequest getServletRequest() {
return this.request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public HttpServletResponse getServletResponse() {
return this.response;
}
public ICacheDelegate getCacheDelegate() {
return cacheDelegate;
}
public void setCacheDelegate(ICacheDelegate cacheDelegate) {
this.cacheDelegate = cacheDelegate;
}
public void addParam(final String key, final String value) {
this.params.put(key, value);
}
public Map getParams() {
return params;
}
public void setParams(final Map<String, String> params) {
this.params = params;
}
public Map getSession() {
return this.session;
}
public void setSession(final Map session) {
this.session = session;
}
public void setParameters(final Map param) {
this.parameters = param;
}
}
applicationContext_MNC.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- database configuration from property file -->
<bean id="BMOAdminDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" lazy-init="default" autowire="default" dependency-check="default">
<property name="driverClass" value="${jdbc.driver}" ></property>
<property name="jdbcUrl" value="${admin.jdbc.url}" ></property>
<property name="user" value="${admin.jdbc.user}" ></property>
<property name="password" value="${admin.jdbc.password}" ></property>
<property name="initialPoolSize" value="3" ></property>
<property name="minPoolSize" value="3" ></property>
<property name="maxPoolSize" value="25" ></property>
<property name="acquireIncrement" value="1" ></property>
<property name="acquireRetryDelay" value="1000" ></property>
<property name="debugUnreturnedConnectionStackTraces" value="true" ></property>
<property name="maxIdleTime" value="300" ></property>
<property name="unreturnedConnectionTimeout" value="300000" ></property>
<property name="preferredTestQuery" value="SELECT COUNT(*) FROM LOCALE_CODE" ></property>
<property name="checkoutTimeout" value="300000" ></property>
<property name="idleConnectionTestPeriod" value="600000" ></property>
</bean>
<bean id="BMOWIRAdminBaseAction" class="com.symcor.wiradmin.web.action.WIRAdminBase Action">
<property name="cacheDelegate">
<ref bean="BMOCacheDelegate" />
</property>
</bean>
<bean id="BMOCacheDelegate" class="com.symcor.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="BMOStatusDBDAO" /></property>
</bean>
<bean id="BMOStatusDBDAO" class="com.symcor.wiradmin.dao.StatusDBDAO">
<property name="dataSource">
<ref bean="BMOAdminDataSource" />
</property>
</bean>
<!-- this bean is set to map the constants which needs to be configured as per
the environment to the java constants file -->
<bean id="envConstantsConfigbean" class="com.symcor.wiradmin.util.constants.Environm entConstantsSetter">
<property name="loginUrl" value="${login.url}"/>
<property name="logoutIR" value="${logout.from.image.retrieval}"/>
<property name="adminModuleUrl" value="${admin.url}"/>
<property name="adminUrlSym" value="${admin.url.sym}"/>
<property name="envProperty" value="${env.property}"/>
</bean>
</beans>
Related
In my app I've been passing my SessionFatory in my method parameters when I need to access my database within those methods. It's instantiated in my Controller using:
#Autowired
private SessionFactory sessionFactory;
And when I need to access my database I use lines like this:
sessionFactory.getCurrentSession().save()
// or
List products = sessionFactory.getCurrentSession().createSQLQuery("SELECT * FROM PRODUCTS").list();
Should I be creating new sessionFactories to get my current session or should is it okay to pass it as a parameter?
edit [added for clarity]:
From HomeController.java:
#Controller
public class HomeController {
#Autowired
private SessionFactory sessionFactory;
//Correlations Insert Handler
//DOCUMENT CREATE
#RequestMapping(value="/documents", method = RequestMethod.PUT)
public #ResponseBody String insertDocument(HttpServletRequest request, HttpServletResponse response){
DocumentControl documentControl = new DocumentControl();
documentControl.insertDocument(request, response, sessionFactory);
return "went through just find";
}
//DOCUMENT READ
#RequestMapping(value="/documents", method = RequestMethod.GET)
public #ResponseBody List<Documents> getAllDocuments(){
//List documents = sessionFactory.getCurrentSession().createQuery("from Documents").list();
DocumentControl documentControl = new DocumentControl();
List documents = documentControl.getAllDocuments(sessionFactory);
return documents;
}
From DocumentControl.java:
public class DocumentControl {
private static Logger logger = Logger.getLogger(DocumentControl.class.getName());
public DocumentControl(){};
//CREATE
public void insertDocument(HttpServletRequest request, HttpServletResponse response, SessionFactory sessionFactory){
Documents document = new Documents(request)
sessionFactory.getCurrentSession().save(document);
}
//READ
public List<DocumentReturn> getAllDocuments(SessionFactory sessionFactory){
List documents = sessionFactory.getCurrentSession().createQuery("from Documents").list();
return documents;
}
private boolean ifProductExists (String productCode, SessionFactory sessionFactory) {
boolean exists = false;
List<Products> productList = sessionFactory.getCurrentSession().createCriteria(Products.class).add( Restrictions.eq("productCode", productCode)).list();
if ( !productList.isEmpty() && productList.size() > 0 ) {
exists = true;
}
return exists;
}
private boolean ifStandardExists (String standardCode, SessionFactory sessionFactory) {
boolean exists = false;
List<Standards> standardList = sessionFactory.getCurrentSession().createCriteria(Standards.class).add( Restrictions.eq("standardCode", standardCode)).list();
if ( !standardList.isEmpty() && standardList.size() > 0 ) {
exists = true;
}
return exists;
}
}
hibernate.cfg.xml:
hibernate-configuration>
<session-factory>
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">100</property>
<property name="hibernate.c3p0.max_size">10</property>
<property name="hibernate.c3p0.max_statements">10</property>
<property name="hibernate.c3p0.min_size">10</property>
<property name="hibernate.c3p0.timeout">100</property>
<mapping class="***.*****.********.model.Documents"/>
</session-factory>
</hibernate-configuration>
persistence-context.xml:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key=" hibernate.use_sql_comments">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<
property name="sessionFactory" ref="sessionFactory" />
</bean>
SessionFactory is a Singleton. Therefore, you should get it from the ApplicationContext (i.e. using the #Autowired annotation). Passing it as a parameter will only complicate your API.
I think that you should leave creation of SessionFactory to the framework you are using and inject it as a resource just as you are doing by now. Besides you are not creating it in your code at all. Good practice is to create separate session for every chunk of data manipulation, if it is not done by a framework ofc. Session should be your main unit of work.
I've encorporated quartz scheduler in diffrent java file in my JSP Struts/Hibernate application. My execute method looks like below:
public void execute(JobExecutionContext jExeCtx) throws JobExecutionException {
try {
userDetailManager = new UserDetailManagerImpl();
userDetailManager.sendMailTxnDetailsEveryNight();
} catch (ApplicationException ex) {
java.util.logging.Logger.getLogger(JobClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
Then im calling sendMailTxnDetailsEveryNight method and looks like:
public void sendMailTxnDetailsEveryNight() throws ApplicationException{
List<RemittanceTransactionBean> rBean = remittanceTransactionDao.getTodayTxnSummary();
return rBean;
}
Im getting nullpointerException at given point :
java.lang.NullPointerException
at com.mtmrs.business.user.impl.UserDetailManagerImpl.sendMailTxnDetailsEveryNight(UserDetailManagerImpl.java:754)
at com.mtmrs.util.common.JobClass.execute(JobClass.java:44)
How do i need to call the getTodayTxnSummary(); so that i dont get any error. I defined the remittanceTransactionDao in applicationContext as well:
<bean id="userDetailManager" parent="abstractTxDefinition">
<property name="target">
<bean class="com.mtmrs.business.user.impl.UserDetailManagerImpl">
<property name="remittanceTransactionDao" ref="remittanceTransactionDao"></property>
</bean>
</property>
</bean>
I tried debugging and see, the remittanceTransactionDao is null. I also tried setting below before calling method remittanceTransactionDao. This way the session variable im using in sendMailTxnDetailsEveryNight is null. I m stuck here.
remittanceTransactionDao = new RemittanceTransactionDaoHibernate(RemittanceTransaction.class);
I removed the classes and configured the follwing in my application-Context Dao.xml.
<bean name="runMeJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.mtmrs.util.common.RunMeJob" />
<property name="jobDataAsMap">
<map>
<entry key="userDetailManager" value-ref="userDetailManager" />
</map>
</property>
</bean>
<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="runMeJob" />
<property name="cronExpression" value="0 0 10,12,14,16,18,20,22,23 * * ?" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="runMeJob" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>
Then i removed everything about the quartz implementaion code whatever i was trying to make, and added this class:
package com.mtmrs.util.common;
import com.mtmrs.business.user.UserDetailManager;
import com.mtmrs.util.logger.MTMRSLogger;
import com.mtmrs.util.logger.ApplicationException;
import java.util.logging.Level;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class RunMeJob extends QuartzJobBean {
UserDetailManager userDetailManager;
public UserDetailManager getUserDetailManager() {
return userDetailManager;
}
public void setUserDetailManager(UserDetailManager userDetailManager) {
this.userDetailManager = userDetailManager;
}
#Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
System.out.print("Entering Class: Job Class , method: execute");
try {
userDetailManager.sendMailTxnDetailsEveryNight();
} catch (ApplicationException ex) {
java.util.logging.Logger.getLogger(RunMeJob.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.print("Exiting Class: Job Class , method: execute");
}
}
Also i downgraded the version of quartz jar to 1.x.
I needed to use a method in userDetailManager (ie sendMailTxnDetailsEveryNight) object as the job that run every 2 hours as specified in the trigger.
Basically i followed this link: Mykong
Hope this can be of help to someone.
I have this situation:
class User
#Entity
#Configurable(preConstruction=true)
public class User extends AbstractBussinessObject implements Serializable {
#OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Warrior> warriors;
...
class UserDto
public class UserDto extends AbstractDto implements Serializable{
private List<WarriorDto> warriors;
private String name;
private String password;
public UserDto() {}
public UserDto(Long id, List<WarriorDto> warriors, String name, String password) {
this.warriors = warriors;
...
class Warrior
#Entity
public class Warrior extends AbstractBussinessObject implements Serializable{
#JoinColumn(name = "user_id")
#ManyToOne
private User user;
...
class WarriorDto
public class WarriorDto extends AbstractDto implements Serializable{
private User user;
...
method in WarriorServiceImpl
#Transactional(readOnly = true)
public List<WarriorDto> getAllWarriors() {
List<Warrior> wars = null;
List<WarriorDto> warsDto = new ArrayList<WarriorDto>();
try {
wars = genericDao.getAll(Warrior.class);
if (wars != null) {
for (Warrior war : wars) {
warsDto.add(createWarriorDto(war));
}
}
} catch (Exception e) {}
return warsDto;
}
method in DAO
#SuppressWarnings("unchecked")
#Override
public <ENTITY> List<ENTITY> getAll(Class<ENTITY> clazz) {
return getEntityManager().createQuery(
"SELECT e FROM " + clazz.getSimpleName() + " e")
.getResultList();
}
applicationContext.xml
<!-- Connection pool -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="2" />
<property name="minIdle" value="2" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${jpa.platform}" />
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="packagesToScan" value="cz.sutak.game" />
</bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Podpora deklarativni demarkace transakci - anotace #Transactional -->
<tx:annotation-driven transaction-manager="txManager" mode="aspectj" />
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="txManager" />
</property>
</bean>
complete code
https://github.com/sutakjakub/game
And if I want call WarriorService.Util.getInstance().getAllWarriors(
new AsyncCallback<List<WarriorDto>>() in widgets it will failure with this message: com.google.gwt.user.client.rpc.StatusCodeException: 500 The call failed on the server; see server log for details.
In Jetty is only this message: [ERROR] 500 - POST /game/warrior (127.0.0.1) 57 bytes
No error message more.
Is problem in serialization (util.List)? Do u have some idea?
Thank you very much.
EDIT:
This is error message in terminal (sorry i didnt look that):
ERROR LazyInitializationException - failed to lazily initialize a collection of role: cz.sutak.game.client.bo.User.warriors, no session or session was closed
The problem is that on the client side Hibernate has no way of fetching the attributes you marked with fetch = FetchType.LAZY. You either need to fetch them eagerly on the server side og null the Hibernate proxies before passing the object graph over the wire.
See my answer in another thread for tips on nulling Hibernate proxies.
Cheers,
Here As you said there is nothing to do with GWT,because its server side code.Even on clien side GWT supports Util.List.
And coming to the original problem.Its with the line wars = genericDao.getAll(Warrior.class);
while accessing this line there is no hibernate session opened.
The resolvers customizeFault method isnt being hit when I set the mapped endpoints below. If I remove it, it gets hit. Any help? The exception is thrown in my resolver class.
MembershipManagementEndpoint.java
package com.openclass.adapter.ws;
#Endpoint
public class MembershipManagementEndpoint {
Spring Config
<bean id="membershipExceptionResolver" class="com.openclass.adapter.ws.resolvers.LisMembershipResolverInterceptor">
<property name="order" value="1"></property>
<property name="mappedEndpoints">
<set>
<value>com.openclass.adapter.ws.MembershipManagementEndpoint</value>
</set>
</property>
</bean>
LisSoapFaultTranslatorExceptionResolver.java
package com.openclass.adapter.ws.resolvers;
public class LisMembershipResolverInterceptor extends LisSoapFaultTranslatorExceptionResolver {
#Override
public boolean handleRequest(MessageContext messageContext, Object endpoint)
throws Exception {
throw new LisMembershipException();
return true;
}
LisSoapFaultTranslatorExceptionResolver.java
public abstract class LisSoapFaultTranslatorExceptionResolver extends
SimpleSoapExceptionResolver implements SoapEndpointInterceptor {
I add to build separate interceptor/resolver for each endpoint and then test in the interceptor/resolver and test for the correct endpoint.
SoapFaultExceptionResolver
#Override
protected final boolean resolveExceptionInternal(MessageContext messageContext, Object endpoint, Exception ex) {
MethodEndpoint methodEndpoint = (MethodEndpoint)endpoint;
if(methodEndpoint != null && methodEndpoint.getBean().getClass().getSimpleName().equalsIgnoreCase(getEndpointClass().getSimpleName()))
{
Assert.isInstanceOf(SoapMessage.class, messageContext.getResponse(),
"SimpleSoapExceptionResolver requires a SoapMessage");
SoapMessage response = (SoapMessage) messageContext.getResponse();
String faultString = StringUtils.hasLength(ex.getMessage()) ? ex.getMessage() : ex.toString();
SoapBody body = response.getSoapBody();
SoapFault fault = body.addServerOrReceiverFault(faultString, getLocale());
customizeFault(messageContext, endpoint, ex, fault);
return true;
}
return false;
}
Config
<bean id="courseSectionExceptionResolver" class="com.test.adapter.ws.resolvers.LisCourseSectionResolverInterceptor">
<property name="order" value="1"></property>
</bean>
<bean id="personExceptionResolver" class="com.test.adapter.ws.resolvers.LisPersonResolverInterceptor">
<property name="order" value="2"></property>
</bean>
<bean id="membershipExceptionResolver" class="com.test.adapter.ws.resolvers.LisMembershipResolverInterceptor">
<property name="order" value="3"></property>
</bean>
<bean id="bdemsExceptionResolver" class="com.test.adapter.ws.resolvers.LisBdemsResolverInterceptor">
<property name="order" value="4"></property>
</bean>
<bean id="outcomeExceptionResolver" class="com.test.adapter.ws.resolvers.LisOutcomeResolverInterceptor">
<property name="order" value="5"></property>
</bean>
<sws:interceptors>
<sws:payloadRoot namespaceUri="http://www.imsglobal.org/services/lis/cmsv1p0/wsdl11/sync/imscms_v1p0">
<bean class="com.test.adapter.ws.resolvers.LisCourseSectionResolverInterceptor"/>
</sws:payloadRoot>
<sws:payloadRoot namespaceUri="http://www.imsglobal.org/services/lis/pms2p0/wsdl11/sync/imspms_v2p0">
<bean class="com.test.adapter.ws.resolvers.LisPersonResolverInterceptor"/>
</sws:payloadRoot>
<sws:payloadRoot namespaceUri="http://www.imsglobal.org/services/lis/mms2p0/wsdl11/sync/imsmms_v2p0">
<bean class="com.test.adapter.ws.resolvers.LisMembershipResolverInterceptor"/>
</sws:payloadRoot>
<sws:payloadRoot namespaceUri="http://www.imsglobal.org/services/lis/bdems1p0/wsdl11/sync/imsbdems_v1p0">
<bean class="com.test.adapter.ws.resolvers.LisBdemsResolverInterceptor"/>
</sws:payloadRoot>
<sws:payloadRoot namespaceUri="http://www.imsglobal.org/services/lis/oms1p0/wsdl11/sync/imsoms_v1p0">
<bean class="com.test.adapter.ws.resolvers.LisOutcomeResolverInterceptor"/>
</sws:payloadRoot>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor">
<property name="logRequest" value="true"/>
<property name="logResponse" value="true"/>
</bean>
</sws:interceptors>
I have a default database and sometimes I have to make a select in another database.
I've searched many blogs and questions here about this, but couldn't make it work.
Tried the http://blog.springsource.org/2007/01/23/dynamic-datasource-routing/ way. Nothing.
Code for RouterDataSource class:
public class RouterDataSource extends AbstractRoutingDataSource {
#Override
protected DataSourceEnum determineCurrentLookupKey() {
return DataSourceContextHolder.getTargetDataSource();
}
}
Code for DataSourceContextHolder class:
public class DataSourceContextHolder {
private static final ThreadLocal<DataSourceEnum> contextHolder = new ThreadLocal<DataSourceEnum>();
public static void setTargetDataSource(DataSourceEnum targetDataSource) {
Assert.notNull(targetDataSource, "Target data source cannot be null");
contextHolder.set(targetDataSource);
}
public static DataSourceEnum getTargetDataSource() {
if (contextHolder.get() != null)
return (DataSourceEnum) contextHolder.get();
else
return DataSourceEnum.DB1;
}
public static void resetDefaultDataSource() {
contextHolder.remove();
}
}
Code for the method calling to change the database:
#Override
public CodeHD getCategoryByCode(String code) throws BusinessException {
DataSourceContextHolder.setTargetDataSource(DataSourceEnum.DATABASE2);
return (CodeHD) persistency.getObject(GETOBJECT_BY_CODE, code);
}
Code for DatasourceEnum class:
public enum DataSourceEnum {
DB1,
DB2;
}
And finally the configuration on my applicationContext.xml:
<bean id="parentDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" abstract="true">
<property name="driverClass" value="oracle.jdbc.pool.OracleDataSource" />
<property name="acquireIncrement" value="10" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="maxStatements" value="50" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="15" />
</bean>
<bean id="database1DS" parent="parentDataSource">
<property name="jdbcUrl" value="jdbc:oracle:thin:#database1:1521:xe" />
<property name="user" value="user" />
<property name="password" value="password" />
</bean>
<bean id="database2DS" parent="parentDataSource">
<property name="jdbcUrl" value="jdbc:oracle:thin:#database2:1521:xe" />
<property name="user" value="user" />
<property name="password" value="password" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="package.RouterDataSource">
<property name="defaultTargetDataSource" ref="database1DS"/>
<property name="targetDataSources">
<map key-type="package.DataSourceEnum">
<entry key="DB1" value-ref="database1DS"/>
<entry key="DB2" value-ref="database2DS"/>
</map>
</property>
</bean>
The problem is that when I set it to DB2 it won't change.
Can anyone help me?
Try to make both static method as non static and pass R reference if the context holder.
First make sure that database2DS is working correctly. Make the defaultTargetDatasource database2DS and verify that it is not using DB1 still and there are no other errors using database2DS as the default. If the AbstractRoutingDataSource fails to resolve a DataSource in the targetDataSources you cannot switch to it.
AbstractRoutingDataSource will only change the DataSource when getConnection is called. Whatever persistence framework you're using is probably caching the Connection and not calling getConnection in between persistency.getObject(). However you are getting your persistency object, try getting a new persistency object after you change the datasource in DataSourceContextHolder. If this solves your problem, try creating a class that maintains your persistency object and handles changing the datasource. That way when you change the datasource you can modify your persistency manager object in one spot.