initialize dependency object dynamiclly in dependency injection? - spring-mvc

To initialize dependency object we put an entry of bean in '/WEB-INF/springmvc-servlet.xml' as:
<bean id="carManager" class="springmvc.service.CarManager">
<property name="carList">
<list>
<ref bean="car1"/>
<ref bean="car2"/>
</list>
</property>
</bean>
for reference bean "car1" and car2" we have entry is:
<bean id="car1" class="springmvc.model.Car">
<property name="id" value="1"/>
<property name="brand" ref="brand1"/>
<property name="model" value="SL 500"/>
<property name="price" value="40000"/>
</bean>
<bean id="car2" class="springmvc.model.Car">
<property name="id" value="2"/>
<property name="brand" ref="brand2"/>
<property name="model" value="607"/>
<property name="price" value="35000"/>
</bean>
so my question is can we prepare "car1" and "car2" bean dynamically. for example in "car1" bean i want car list whoes value is above 40000 so for that i have to take data from DB so how can i call my service or DB query to prepare such bean is it possible?

You can implement BeanDefinitionParser and override appropriate method in it.
and use
BeanDefinitionBuilder messageProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition(MessagingPostProcessor.class);
messageProcessorBuilder.addConstructorArgValue(StringUtils.split(packageNames, ","));
registry.registerBeanDefinition(MessagingPostProcessor.class.getName(), messageProcessorBuilder.getBeanDefinition());

Related

Configuring MyBatis with Spring MVC for multiple datasources

I have been trying to configure MyBatis with Spring MVC to work with multiple databases. I have a page which is trying to connect to one of the DB's to fetch data, so that it can be populated into the drop-down boxes.
Now I am not sure what is wrong with this configuration, but I am receiving the following error:
]] Root cause of ServletException. org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLException: ORA-06576: not a valid function or procedure name
I am providing the XML file here for your reference
<bean id="dataSource1"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#1.1.2.5:1529:DITOS" />
<property name="username" value="return" />
<property name="password" value="return" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage"
value="p.com.ent.appl.return.dev.dao,p.com.ent.appl.return.dep.dao,p.com.ent.appl.return.dao.otheruser" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1" />
</bean>
<!-- Declare a transaction manager -->
<bean id="cashReturnTx"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource1" />
</bean>
<!-- define the SqlSessionFactory, notice that configLocation is not needed
when you use MapperFactoryBean -->
<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="configLocation" value="WEB-INF/mybatis/sqlmap-config.xml" />
<!-- <property name="mapperLocations" value="classpath:/com/vrn/ent/dev/daoxml/*.xml"
/> -->
<property name="mapperLocations"
value="classpath*:/p/com/ent/appl/return/**/daoxml/*.xml" />
</bean>
<bean id="sqlSession1" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory1" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#4.24.80.15:1522:LM" />
<property name="username" value="RETURN" />
<property name="password" value="OWNER" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage"
value="p.com.ent.appl.return.dev.dao,p.com.ent.appl.return.dep.dao,p.com.ent.appl.return.dao.otheruser" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<bean id="otherUserTx"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- define the SqlSessionFactory, notice that configLocation is not needed
when you use MapperFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="WEB-INF/mybatis/sqlmap-config.xml" />
<!-- <property name="mapperLocations" value="classpath:/com/vrn/ent/dev/daoxml/*.xml"
/> -->
<property name="mapperLocations"
value="classpath*:/p/com/ent/appl/return/**/daoxml/*.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
</beans>
According to the exception: BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLException: ORA-06576: not a valid function or procedure name, a DB is hit.
Read about error ORA-06576.
Issue is likeky be related to how the procedure is called. Right way is { CALL MyProcedure (#arg0, #arg1) }
Configuration shows that same mappers may be used with both datasources, what happens then if target schemas are different?

vertica with spring jdbc template

Hi im having trouble configuring a datasource to vertica (6.1.3) with spring (4.2.x).
getting this error..any ideas on what i am missing? RefMetricMappingDao extends NamedParameterJdbcDaoSupport.
<bean id="dataSource2" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${vertica.driver.classname}"/>
<property name="url" value="${vertica.connection.string}"/>
<property name="username" value="${vertica.connection.username}"/>
<property name="password" value="${vertica.connection.password}"/>
</bean>
<bean name="refMetricMappingDao" class="RefMetricMappingDao">
<property name="dataSource" ref="dataSource2"/>
</bean>
java.lang.AbstractMethodError: com.vertica.jdbc.VerticaConnectionImpl.isValid(I)Z
at org.apache.commons.dbcp2.DelegatingConnection.isValid(DelegatingConnection.java:918)
at org.apache.commons.dbcp2.PoolableConnection.validate(PoolableConnection.java:283)
at org.apache.commons.dbcp2.PoolableConnectionFactory.validateConnection(PoolableConnectionFactory.java:357)
at org.apache.commons.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:2307)
at org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2290)
at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2039)
at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1533)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:615)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:680)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:707)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:757)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.query(NamedParameterJdbcTemplate.java:192)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForList(NamedParameterJdbcTemplate.java:250)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForList(NamedParameterJdbcTemplate.java:257)
at
duh...vertica comes with a datasource class
<bean id="dataSource2" class="com.vertica.jdbc.DataSource">
<property name="URL" value="${vertica.connection.string}"/>
<property name="userID" value="${vertica.connection.username}"/>
<property name="password" value="${vertica.connection.password}"/>
<property name="searchPath" value="${vertica.connection.schemaname}"/>
<property name="batchInsertDirect" value="true"/>
</bean>

Spring+Quartz Fire job execution only if previous has finished

I'm using SpringMVC (4.x) along with Quartz (2.x). I'm setting a bean defnition file to fire a simple job, but wnat to make sure that the job is only fired if the previous execution of that job has already finished. Is there a parameter I can inform to SimpleTriggerFactoryBean in order to avoid concurrent execution?
By using the repeatInterval property, won't I fire simultaneous jobs?
My Quartz Bean Definition XML
<bean id="autoPusherJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="br.teste.AutoMessagePusherJob" />
<property name="jobDataAsMap">
<map>
<entry key="userName" value="SystemCronJob"/>
<entry key="message">
<bean class ="br.teste.model.Message"/>
</entry>
</map>
</property>
<property name="durability" value="true" />
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="autoPusherJob" />
<property name="startDelay" value="1000" />
<property name="repeatInterval" value="1000" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="autoPusherJob" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
Your job class needs to be annotated with the DisallowConcurrentExecution annotation.

Custom Argument Resolver for ExceptionHandlerExceptionResolver

I'm trying to use a custom argument inside a method annotated with the ExceptionHandler in spring mvc 3.2 to handle an exception.
However I still get this exception when the method is executed:
java.lang.IllegalStateException: No suitable resolver for argument[1] [type=com.example.domain.CustomArgument]
The Controller method looks like:
#ExceptionHandler(IOException.class)
#ResponseBody
public Error handleIOException(IOException ex, CustomArgument customArgument) {
return new Error(customArgument.getMessage());
}
And I'm using the following xml config:
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="com.example.spring.CustomArgumentWebArgumentResolver" scope="singleton">
<constructor-arg ref="customArgumentService" />
</bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<bean id="customArgumentService" class="com.example.service.CustomArgumentService" scope="singleton" />
<bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver" scope="singleton">
<property name="customArgumentResolvers">
<list>
<bean class="com.example.service.CustomArgumentService" scope="singleton">
<constructor-arg ref="customArgumentService" />
</bean>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" scope="singleton">
<property name="defaultErrorView" value="forward:/error" />
</bean>
And I believe mvc:annotation-driven is already assigning a ExceptionHandlerExceptionResolver, so how can I add the customArgumentResolver to that.
Any help would be greatly appreciated.
For several ExceptionResolvers try using HandlerExceptionResolverComposite. Something like this:
<bean class="org.springframework.web.servlet.handler.HandlerExceptionResolverComposite">
<property name="exceptionResolvers">
<list>
<bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
<constructor-arg ref="exceptionHandlerExceptionResolver" />
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<constructor-arg ref="simpleMappingExceptionResolver" />
</bean>
</list>
</property>
<property name="order" value="0"/>
</bean>

i18n with Spring MVC, skip RequestMapping

I have set up i18n to my web app using Spring.It works fine.But I have a problem.When I click link to different language,from, lets say edit_user page. The request url is generated as '/edit_user.htm?lang=de'.Controller class receives this request and run editUser method based on #RequestMapping(value = { "edit_user" }). How to avoid this from happening.I just want my web app to be able to simply change the locale without reaching controller class methods when clicked on "change language links". My spring-config-servlet.xml is as following.
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:i18n/messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate" />
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="pretty" value="text/html" />
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
<property name="defaultViews">
<list>
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.xstream.XStreamMarshaller" />
</constructor-arg>
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
....
</property>
<property name="defaultErrorView" value="errorPage" />
</bean>
Hm... Interesting.
UserController class receives this request:
en | de
for URL http://www.example.com/AppName/User/edit_user.htm?lang=de and run editUser method.
But you can change your links to:
EN | DE
and now when user click link to different language HomeController class receives request /?lang=de, web app change the locale and redirect user to the root page http://www.example.com/AppName/?lang=de.
Is this behavior acceptable for your application?
Otherwise I guess you have to filter request params for all controller classes if you want to find another solution.

Resources