Adt message converters - INTEGERS come as nulls - java

I am using following configuration for handling OracleAQ with adt payload...
<bean id="messageConverter"
class="org.springframework.data.jdbc.jms.support.converter.oracle.MappingAdtMessageConverter">
<constructor-arg>
<bean class="org.springframework.data.jdbc.jms.support.oracle.StructDatumMapper">
<constructor-arg index="0" value="MY_QUEUE"/>
<constructor-arg index="1" value="MyMappedClass"/>
</bean>
</constructor-arg>
</bean>
the problem is that after dequeuing I am getting on java side null values for fields with INTEGERs and non null values for other fields.
MyMappedClass#649fe46f[
id=<null>
id2=<null>
time=2013-02-22 14:57:11.0
user=LUKAS
]
In queue table these values exists as not nulls.
What can be the reason. I expected bad mappings, but I don't see anything wrong there.
Those fields are mapped as Types.INTEGER.
Do you have maybe idea what can be the reason?

Finally I've found that there are mistakes in generated mapping files. For Long field I had Integer setter. That was the reason why reflection api during conversion process regarded those fields as non writeable. So it was not library version or configuration problem.

Related

Inject Resolved Properties Object to Another Bean

I'd like to inject a java.util.Properties object into another bean through XML config. I have tried the solution listed here without success, presumably because the bean is being injected before the property resolution occurs. Is there a way that I can force the java.util.Properties object to be resolved before being injected to my class?
Below is the trimmed/edited version of what I have. PropertiesConsumingClass does receive the merged, but unresolved properties of a, b, and c properties files.
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="allProperties" />
</bean>
<bean id="allProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="propertiesArray">
<util:list>
<util:properties location="classpath:a.properties" />
<util:properties location="classpath:b.properties" />
<util:properties location="classpath:c.properties" />
</util:list>
</property>
</bean>
<bean class="PropertiesConsumingClass">
<constructor-arg index="0" ref="allProperties" />
</bean>
Your example doesn't work because what Spring calls a property isn't the same thing as what Java calls a property. Basically, a Spring property lives in a <property> tag, and this is what gets resolved by PropertyPlaceholderConfigurer. You can also use property placeholders inside #Value annotations. Either way you have a string with ${} placeholders that get resolved, possibly the string is converted to the correct type, and injected into your bean.
java.util.Properties are used to resolve placeholders in Spring properties, but they aren't considered for resolution themselves. Any properties in a., b., or c.properties will be substituted into Spring property placeholders, but PropertyPlaceholderConfigurer doesn't know or care if the values it gets from those files have ${} in them.
Now, Spring Boot does resolve placeholders inside its config files, but it has special sauce to accomplish that. It's also a very opinionated library that wants to control your app's lifecycle and does lots of magical things behind the scenes, so it's very hard to adopt or drop except at the very beginning of a project.

What exactly do the following SpEL expression?

I have some doubt about what exactly do these 3 Spring SpEL example:
1) FIRST EXAMPLE:
<bean id="rewardsDb" class="com.acme.RewardsTestDatabase">
<property name="keyGenerator" value="#{strategyBean.databaseKeyGenerator}" />
</bean>
It seems to me that this code snippet injet an inner property named databaseKeyGenerator (that is inside the strategyBean bean). So in this case SpEL is used to access to a specific bean property in the classica OO logic. Is it true?
2) SECOND EXAMPLE:
<bean id="strategyBean" class="com.acme.DefaultStrategies">
<property name="databaseKeyGenerator" ref="myKeyGenerator"/>
</bean>
It seems to me that SpEL is not used, or am I missing something?
3) THIRD EXAMPLE:
<bean id="taxCalculator" class="com.acme.TaxCalculator">
<property name="defaultLocale" value="#{ systemProperties['user.region'] }"/>
</bean> Equivalent
It is used to inject a property value taken from a property file
Is it correct or I a missing something or am I misinterpreting the SpEL logic?
The first and second examples come together. The second actually uses no SpEL at all. Its sole purpose is to help understand the first one. So you are not missing something regarding the first two.
As for the third one, systemProperties is a predefined variable and you use it to access system properties. Except from the standard VM system properties you can also access those that you pass with -D when starting the application.
You can access a property file the same way, after creating a bean to reference them, by using the bean id instead of systemProperties. For example
<util:properties id="appProps" location="classpath:application.properties" />
and then
<property name="propOne" value="#{appProps['some.property'] }"/>

constructor-arg ref from properties in spring

I have bean which has to be binded at run time.
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="${requiredBean:mysql}"/>
</bean>
<bean id="mysql" class="xxx.xxx.xxxxxx">
</bean>
<bean id="mongo" class="xxx.xxx.xxxxxx">
</bean>
In the property file I added the property
requiredBean=mongo
But due to some reason the requiredBean from the properties file is not picked up by the spring (The properties file is configured correctly and all other properties are loading properly except for this one).
I just want to know if the syntax that I used for declaring the arg for constructor aa ref is right or is there any other way to declare it.
Pls help me to resolve this.
Let me know if the question is not clear.
if you are sure (as you already mentioned in the content of .properties) that you are mentioning the right property(no spelling error), then problem is something else, and not the property itself. Try removing the default value . It must throw exception like :::: java.lang.IllegalArgumentException: Could not resolve placeholder 'XYZ' in string value "${XYZ}". If it does not throw this exception, issue is not related to this bean at all.

How do I load a bean value from a file with job parameter substitution?

In my spring batch project I can do something like this:
<bean id="exampleTasklet" class="my.custom.Tasklet">
<property name="message" value="job parameter value: #{jobParameters['arg1']}"/>
</bean>
and the message property will have a value taken from the spring batch job parameters. However, the value that I actually want to assign is very large and I don't want to put it in the xml file. I know this syntax doesn't work, but I would like to do something like:
<bean id="exampleTasklet" class="my.custom.Tasklet">
<property name="message" read-value-from-file="/path/to/file.txt"/>
</bean>
and that file would contain the line "job parameter value: #{jobParameters['arg1']}" which spring will parse as if the file content was in a value="" attribute.
Is there a nice way to do this?
I think what you are looking for is a PropertyPlaceholderConfigurer.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/path/to/file.properties" />
<property name="placeholderPrefix" value="#{" />
<property name="placeholderSuffix" value="}" />
</bean>
This is run by Spring as a bean processor and will attempt to resolve placeholder tokens. There is a default instance that will resolve against system properties, using this notation: ${propertyname}. For your notation, you would need to specify the placeholderPrefix/Suffix. When there are multiple bean processors, the order is determined by the order property. By default, if a processor fails to resolve a placeholder, execution fails, but this can be altered by setting ignoreUnresolvablePlaceholders. Since the mechanism is property driven, you probably want to consider a notation like:
<property name="message" value="job parameter value: #{jobParameters.arg1}"/>
Or, if what you're trying to convey is that arg1 is also a parameter, you might try:
<property name="message" value="job parameter value: #{jobParameters.${arg1}}"/>
Spring loops over the bean processors until no replacements are performed, or an exception is raised. So defining a property as ${something.${orOther}} is valid.
I would suggest you to use a String as file name and in your bean open that file.
I'm not sure if I get your problem right. I'm just suggesting something like Spring MessageBundle
Something like this:
<bean id="exampleTasklet" class="my.custom.Tasklet">
<property name="messagePath" location="/path/to/file.txt"/>
</bean>
And in your exampleTasklet read the file and do your thing (I'm not sure what it is)
If anybody came here to do something like this from a properties-file:
If you want a property from a .properties-file to appear in the JobParameters, you won't find ready-to-use solution. You can do the following:
Wrap a bean around your properties file.
Pass this bean to another one which has access to the JobParameters and can pump the properties from the file into that class.
Then you should be able to access your properties with Spring's Expression Language and do something like:
<bean id="myBean" class="my.custom.Bean">
<property name="prop" value="#{jobParameters['arg1']}"/>
</bean>
Alternatively, I think the solution proposed by Devon_C_Miller is much easier. You don't have the properties in your JobParameters then. But if the replacement in the XML configuration is the only thing you want, you only have to change your placeholders to:
${myPropFromFile}
Happy batching, everyone ;-)

Is it possible to have multiple PropertyPlaceHolderConfigurer in my applicationContext?

I need to load a specific applicationContext.xml file according to a given system property. This itself loads a file with the actual configuration. Therefore I need two PropertyPlaceHolderConfigurer, one which resolves the system param, and the other one within the actual configuration.
Any ideas how to do this?
Yes you can do more than one. Be sure to set ignoreUnresolvablePlaceholders so that the first will ignore any placeholders that it can't resolve.
<bean id="ppConfig1" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<value>classpath*:/my.properties</value>
</list>
</property>
</bean>
<bean id="ppConfig2" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="false"/>
<property name="locations">
<list>
<value>classpath*:/myOther.properties</value>
</list>
</property>
</bean>
Depending on your application, you should investigate systemPropertiesMode, it allows you to load properties from a file, but allow the system properties to override values in the property file if set.
Another solution is to use placeholderPrefix property of PropertyPlaceholderConfigurer. You specify it for the second (third, fourth...) configurer, and then prefix all your corresponding placeholders, thus there will be no conflict.
<bean id="mySecondConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:/myprops.properties"
p:placeholderPrefix="myprefix-"/>
<bean class="com.mycompany.MyClass" p:myprop="${myprefix-value.from.myprops}"/>
Beware -- there might be a bug related to multiple configurers. See http://jira.spring.io/browse/SPR-5719 for more details.
I'm unable to get multiple to work locally... but I'm not yet blaming anyone but myself.
On my own side, playing with PropertyPlaceholderConfigurer both properties :
order (should be lower for first accessed/parsed PPC)
ignoreUnresolvablePlaceholders ("false" for first accessed/parsed PPC, "true" for next one)
and also give 2 distinct id(s) to both PPC (to avoid one to be overwritten by the other)
works perfectly
Hope it helps
You can't do this directly, and this JIRA issue from Spring explains why (check the comment from Chris Beams for a detailed explanation):
https://jira.springsource.org/browse/SPR-6428
However, he does provide a workaround using Spring 3.1 or later, which is to use the PropertySourcesPlaceholderConfigurer class instead of PropertyPlaceholderConfigurer class.
You can download a Maven-based project that demonstrates the problem and the solution from the Spring framework issues github:
https://github.com/SpringSource/spring-framework-issues
Look for the issue number, SPR-6428, in the downloaded projects.
We have the following approach working:
<util:properties id="defaultProperties">
<prop key="stand.name">DEV</prop>
<prop key="host">localhost</prop>
</util:properties>
<context:property-placeholder
location="file:${app.properties.path:app.properties}"
properties-ref="defaultProperties"/>
System property app.properties.path can be used to override path to config file.
And application bundles some default values for placeholders that cannot be defined with defaults in common modules.
Just giving 2 distinct ids worked for me. I am using spring 3.0.4.
Hope that helps.
In case, you need to define two PPC's (like in my situation) and use them independently. By setting property placeholderPrefix, you can retrieve values from desired PPC. This will be handy when both set of PPC's properties has same keys, and if you don't use this the property of ppc2 will override ppc1.
Defining your xml:
<bean name="ppc1"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="ref to your props1" />
<property name="placeholderPrefix" value="$prefix1-{" />
</bean>
<bean name="ppc2"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="ref to your props2" />
<property name="placeholderPrefix" value="$prefix2-{" />
</bean>
Retrieving during Run time:
#Value(value = "$prefix1-{name}")
private String myPropValue1;
#Value(value = "$prefix2-{name}")
private String myPropValue2;

Categories