How to use SpEL in Spring? - java

I have declare bean like these:
<bean id="kenny"
class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="Price Tag"></property>
<property name="age" value="27"></property>
<property name="instrument">
<bean class="com.springinaction.springidol.Saxophone"/>
</property>
</bean>
<bean id="carl"
class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="#{kenny.song}" />
<property name="instrument">
<bean class="com.springinaction.springidol.Saxophone"/>
</property>
</bean>
Why the song property of carl is "#{kenny.song}" not "Price Tag"?
What am I missing to use SpEL in Spring?

Related

Weird numbers in generated CSV with Spring Batch

I am developing a Spring batch to get data from a table and into a CSV file. This is the table I am extracting data from:
CREATE TABLE TMP_SYNCHRONIZED_RSLT
(SERIAL_QA NUMBER(20) UNIQUE
, NB_RECENT VARCHAR2(10)
, NB_ARTICLE VARCHAR2(2)
);
I have my reader as follows:
<bean id="serialNumbersReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
<property name="fetchSize" value="${batch.job.fetch.interval}" />
<property name="dataSource" ref="dataSource" />
<property name="rowMapper">
<bean class="org.springframework.jdbc.core.BeanPropertyRowMapper">
<property name="mappedClass" value="ca.org.serialNumbersGenerationBatch.batch.synchronization.dto.ExtractSerialNumbersDto" />
</bean>
</property>
<property name="sql">
<value>
<![CDATA[
SELECT SERIAL_QA, NB_RECENT, NB_ARTICLE from TMP_SYNCHRONIZED_RSLT
]]>
</value>
</property>
</bean>
And my writer:
<bean id="csvWriteSerialNumbers"
class="org.springframework.batch.item.file.FlatFileItemWriter">
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="delimiter" value=";" />
<property name="fieldExtractor">
<bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="serialQa, nbRecent, nbArticle" />
</bean>
</property>
</bean>
</property>
<property name="encoding" value="${csv.encoding}" />
<property name="headerCallback">
<bean class="fr.canalplus.cgaweb.batch.common.writer.StringHeaderFooterCallback">
<property name="header" value="SERIAL_QA;NB_RECENT;NB_ARTICLE" />
</bean>
</property>
<property name="resource" value="file:${tmp.dir}/serialNumbers.csv" />
</bean>
my csv.encoding = ISO-8859-1. And I put String in all of my DTO attributes.
This generates weird numbers like 2,49254E+12 instead of 24925418071 in my CSV under SERIAL_QA. Any idea on how to resolve this without changing the column type?

Camel-Mybatis Open session Exception

I'm using Camel-Mybatis version 2.12.0.redhat-610379, when we trying to start the bundle thru karaf container the following exception throws. Please advice.
org.apache.ibatis.exceptions.PersistenceException:
Error opening session. Cause: java.lang.NullPointerException
Cause: java.lang.NullPointerException
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23)[280:org.mybatis.mybatis:3.2.5]
at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:88)[280:org.mybatis.mybatis:3.2.5]
at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSession(DefaultSqlSessionFactory.java:43)[280:org.mybatis.mybatis:3.2.5]
at org.apache.camel.component.mybatis.MyBatisProducer.process(MyBatisProducer.java:51)[282:org.apache.camel.camel-mybatis:2.12.0.redhat-611412]
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:110)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:105)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:279)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.DefaultErrorHandler.process(DefaultErrorHandler.java:56)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:166)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.processByErrorHandler(TransactionErrorHandler.java:218)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.process(TransactionErrorHandler.java:99)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.process(TransactionErrorHandler.java:112)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.processByErrorHandler(TransactionErrorHandler.java:218)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler$1.doInTransactionWithoutResult(TransactionErrorHandler.java:181)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:33)[149:org.apache.servicemix.bundles.spring-tx:3.2.9.RELEASE_1]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131)[149:org.apache.servicemix.bundles.spring-tx:3.2.9.RELEASE_1]
at org.apache.camel.spring.spi.TransactionErrorHandler.doInTransactionTemplate(TransactionErrorHandler.java:174)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.processInTransaction(TransactionErrorHandler.java:134)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.process(TransactionErrorHandler.java:103)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.spring.spi.TransactionErrorHandler.process(TransactionErrorHandler.java:112)[150:org.apache.camel.camel-spring:2.12.0.redhat-611412]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:147)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:69)[144:org.apache.camel.camel-core:2.12.0.redhat-611412]
at java.util.TimerThread.mainLoop(Timer.java:555)[:1.7.0_01]
at java.util.TimerThread.run(Timer.java:505)[:1.7.0_01]
Caused by: java.lang.NullPointerException
at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:83)[280:org.mybatis.mybatis:3.2.5]
... 32 more
Bean.xml
<bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value=""/>
<property name="user" value=""/>
<property name="password" value="" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<argument ref="ds" />
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="mybatisConfig" class="org.springframework.core.io.ClassPathResource">
<argument value="SqlMapConfig.xml" />
</bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" ref="mybatisConfig"/>
<property name="mapperLocations">
<array value-type="org.springframework.core.io.Resource">
<bean class="org.springframework.core.io.ClassPathResource">
<argument value="mappings/QueryMessaging.xml" />
</bean>
</array>
</property>
</bean>
<bean id="sqlSessionFactory" class="org.apache.ibatis.session.SqlSessionFactory" factory-ref="sqlSessionFactoryBean"
factory-method="getObject" />
<bean id="myBatis" class="org.apache.camel.component.mybatis.MyBatisComponent">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
</bean>
Connections and configurations are created properly, the bug I have made was in bean.xml i have used myBatis bean id, and camel route i have type as mybatis, due to case-sensitive, no environment was created, sorry for that.

Reading Dual/Multiple Properties in Spring

I'm trying to read the application specific properties from database, and I'm trying to keep the database credentials in properties file.
So I need to load both properties (File and DB), while the application is
loading.
I'm having my configuration as follows.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="WEB-INF/config/db.properties"/>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="properties">
<bean class="org.apache.commons.configuration.ConfigurationConverter" factory-method="getProperties">
<constructor-arg>
<bean class="org.apache.commons.configuration.DatabaseConfiguration">
<constructor-arg type="javax.sql.DataSource" ref="postgresqlDataSource"/>
<constructor-arg value="TBL_APP_SETTINGS"/>
<constructor-arg value="PROP_KEY"/>
<constructor-arg value="PROP_VALUE"/>
</bean>
</constructor-arg>
</bean>
</property>
</bean>
<bean id="postgresqlDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="url" value="${db.url}"/>
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.pass}"/>
<property name="initialSize" value="1"/>
<property name="maxActive" value="5"/>
<property name="validationQuery" value="SELECT 1"/>
<property name="timeBetweenEvictionRunsMillis" value="5000"/>
<property name="removeAbandonedTimeout" value="60"/>
<property name="minEvictableIdleTimeMillis" value="30000"/>
<property name="minIdle" value="3"/>
</bean>
It's throwing error for ${db.url}
please help how to do this? thanks in advance.
The easiest way is to externalize some of your config properties the guide is on spring.io site. You can pass properies as java system properties or command line arguments
The second way is to write your own PropertyPlaceholderConfigurer which will read properties from application.yml and from the database
I believe the easiest way you can do it is writing credentials into the spring xml and import it to your main xml and reference them as beans:
<bean id="dbUrl" class="java.lang.String">
<constructor-arg type="java.lang.String" value="jdbc://..."/>
</bean>
... same for dbUser and dbPassword
And then refer to the value using ref.

ReloadingPropertyPlaceholderConfigurer

For some reason the ReloadablePropertiesFactoryBean doens't seem to do what I expect. When I change a property in the test.properties file I get a log message saying:
9979 [timer] INFO com.krest.core.properties.ReloadablePropertiesFactoryBean - Reloading Properties...
But for some reason nothing happens. The old property value is still set on my test bean. Does anybody know why this is? I use Spring 3 and my configuration looks like this:
<bean id="configproperties"
class="com.krest.core.properties.ReloadablePropertiesFactoryBean">
<property name="location"
value="classpath:test.properties" />
</bean>
<bean id="propertyConfigurer"
class="com.krest.core.properties.ReloadingPropertyPlaceholderConfigurer">
<property name="properties" ref="configproperties" />
<property name="reloadingPlaceholderPrefix" value="rel{" />
<property name="reloadingPlaceholderSuffix" value="}" />
</bean>
<bean id="mybean" class="nl.mycompany.TestBean">
<property name="message" value="rel{timer-delay}" />
</bean>
<!-- regularly reload property files. -->
<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<bean id="reloadProperties"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="period" value="1000" />
<property name="runnable">
<bean class="com.krest.core.properties.ReloadConfiguration">
<property name="reconfigurableBeans">
<list>
<ref bean="configproperties" />
</list>
</property>
</bean>
</property>
</bean>
</property>
</bean>

method-invoking Spring bean

I've declared the following bean in my Spring config
<bean id="templateCacheClearingTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay" value="5000" />
<property name="period" value="5000" />
<property name="timerTask">
<bean class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="templateMailService" />
<property name="targetMethod" value="clearCache" />
</bean>
</property>
</bean>
This should cause the clearCache() method of the templateMailService bean to be invoked every 5000ms, but nothing appears to be happening. Am I missing something?
Cheers,
Don
I think you need:
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="templateCacheClearingTask"/>
</list>
</property>
</bean>
In addition to what you already have.

Categories