Unsatisfied Dependency Exception in Spring boot - java

I have a properties XML file as following :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="sample.findAll">
<![CDATA[
The SQL query goes here
]]>
</entry>
</properties>
And a config file as following :
#ImportResource("classpath:sql/find-all-sample-native-query.xml")
#Configuration
public class SampleFindAllConfig {
#Value("#{sample.findAll}")
private String findAllQuery;
#Bean
public String findAllSampleNativeQuery() {
return findAllQuery;
}
}
I'm injecting the Bean in the DAO class as following :
#Inject
private String findAllAnomalieNativeQuery;
But I get this error when I run my application :
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'sampleDAO': Unsatisfied dependency
expressed through field 'findAllSampleNativeQuery'; nested exception
is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'sampleFindAllConfig': Unsatisfied
dependency expressed through field 'findAllQuery'; nested exception is
org.springframework.beans.factory.BeanExpressionException: Expression
parsing failed; nested exception is
org.springframework.expression.spel.SpelEvaluationException: EL1008E:
Property or field 'sample' cannot be found on object of type
'org.springframework.beans.factory.config.BeanExpressionContext' -
maybe not public?
How can I solve this ?

There are two problems with the code.
Problem 1: Use #PropertySource to load with property values with #Value
#ImportResource imports beans definitions, usually in conjunction with XML Spring configuration.
To load property values for #Value from a configuration file, use #PropertySource.
Problem 2: Reference properties using the ${...} syntax
#{sample.findAll} is a SpEL expression. It asks Spring to evaluate sample.findAll, using sample as a bean. Since there is no bean of that name in the context, Spring rightly complains that there is no such bean.
To load the value of the property sample.findAll from a configuration source, use the syntax ${sample.findAll}.
The following code will work:
#Configuration
#PropertySource("classpath:sql/find-all-sample-native-query.xml")
public class SampleFindAllConfig {
#Value("${sample.findAll}")
private String findAllQuery;
#Bean
public String findAllSampleNativeQuery() {
return findAllQuery;
}
}

Related

Upgrading from Springboot 2.1.4.RELEASE to 2.5.0 giving IllegalArgumentException on runtime

I upgraded springboot2.1.4.RELEASE to 2.5.0 ,In local, it is able to run fine and read from the application.properties file, but when I try to deploy in aws ECS it is giving the following error. Any pointers will help
Error:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cloudPlatformSecuirtyResourceServerConfig': Unsatisfied dependency expressed through field 'uaaResourceInfo'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'UAAResourceInfoConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'moa.aws.secrets.uaa.clientId' in value "${moa.aws.secrets.uaa.clientId}"
The application.yml
uaa:
accessTokenURI: ${uaa.accessTokenURI}
clientId: ${moa.aws.secrets.uaa.clientId}
clientSecret: ${moa.aws.secrets.uaa.clientSecret}
clientScope: oa.ups.reader,uaa.resource
The code which is calling the bean
#Configuration
#Profile({"security"})
public class UAAResourceInfoConfig {
#Value("${uaa.accessTokenURI}")
private String uaaAccessTokenURI;
#Value("${uaa.clientId}")
private String uaaClientId;
#Value("${uaa.clientSecret}")
private String uaaClientSecret;
#Value("${uaa.clientScope}")
private String uaaClientScope;
#Bean("UAAResourceInfo")
public UAAResourceInfo uaaResourceInfo() {
return new UAAResourceInfo(uaaAccessTokenURI, uaaClientId, uaaClientSecret, uaaClientScope);
}
}
The only difference between application.properties file and Secrets Manager of aws is , in the properties file the properties are stored individually like
moa.aws.secrets.uaa.clientId=xxx
moa.aws.secrets.uaa.clientSecret=xxxx
moa.aws.secrets.moa.db_url=xxxxx
moa.aws.secrets.moa.db_username=xxxx
moa.aws.secrets.moa.db_password=xxxx
But in Secrets Manager, they may be stored in a json format
moa.aws.secrets={"tenantId": "xxxxx","moa.db_url": "xxxx","moa.db_username": "xxx","moa.db_password": "YOUR_LOCAL_DB_PASS","uaa.clientId": "xxxxxx","uaa.clientSecret": "xxxxx","uaa.scope": "xxxx"}

Spring boot: #Value having issues with bean defined in dependency

I have a spring boot application, say A, which has a bean defined in xml:
<bean class="com.learning.MyBean" name="myBean">
<property name="maxAngle" value="360" ></property>
</bean>
Bean is:
public class MyBean {
#Value("${maxAngle}")
public void setMaxAngle(double maxAngle) {
....
}
}
When I run A independently, all is fine. But when I include it as dependency in another spring boot application, then I get error related to injection of maxAngle:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myBean': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'maxAngle' in value "${maxAngle}"
What can be the issue here?
#Value annotation is used to bind properties defined in application.properties or application.yaml.
Try adding maxAngle=360 to application.properties or application.yaml and remove it from bean XML defination

How to pass return value of a bean to other using Spring MVC

I have a spring bean as follows
package com.test;
#Component
public class Sample{
#Value("${url}")
private String url = null;
public String getURL(){
return "test"+url;
}
}
I have another bean in my context.xml file, which consumes url from above bean
<bean id="build" class="com.test.Consumer">
<property name="url" value="#{new com.test.Sample().getPassword()}"/>
</bean>
But it fails with error below:
java.lang.IllegalStateException: Failed to load ApplicationContext
Expression parsing failed; nested exception is java.lang.NullPointerException
Is this correct: value="#{new com.test.Sample().getURL()}" ?
The correct way would be like this:
#{sample.url}
Where sample is the name of the Sample bean (default name is a name of the class with the first letter converted to lower case) and url is the name of the property you want to get from that bean.
You can check this link for more details: https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/expressions.html#expressions-beandef

How to autowire spring.xml defined beans into #Component Beans

I have a large Spring Project, whose beans are mostly created via the #Component annotation on classes. I'm slowly tring to move the bean definition to the spring.xml config file.
I however, get a the following error whenever I try to autowire a bean created in the xml config file into a bean created via the #Component annotation.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ComponentBean' defined in class path resource [spring.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'xmlBean' of bean class [myproject.XmlBean]: Bean property 'xmlBean' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
In my spring.xml:
<bean id="xmlBean" class="myproject.XmlBean" />
Trying to autowire beans into #Component beans as follows does not work:
#Component
class ComponentBean {
#Autowired
private XmlBean xmlBean;
// Bean setters and getters
}
Is there a way by which I could marsh up the two, as I slowly port my bean definitions to the spring.xml config file.

Any way to override bean definition for spring data jpa repository?

We have a sample app that showcases some things we are doing client side. It pulls in a few internal libraries to get everything functional. It dummies in some hard-coded data so it doesn't have to be concerned with any kind of persistence mechanism.
In some of these libraries that are pulled in, there are spring data jpa repositories. Something like this:
public interface MyLibraryEntityRepository extends JpaRepository<MyLibraryEntity, Long>
{
//...
}
When the server starts up, I get an error like this:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myLibraryEntityRepository': Cannot create inner bean '(inner bean)#788f64f1' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#788f64f1': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined
It can't find the entityManager, but I don't want to have to use an entityManager. So, in an attempt to override the myLibraryEntityRepository bean, I added the following to my Java config:
#Bean
public MyLibraryEntityRepository getMyLibraryEntityRepository()
{
return myDummyImpl();
}
However, this results in the same error.
Is there any way I can override the bean definition for the spring data jpa repository so that I can use my own dummy implementation and not have to configure an entityManager in my app?
You can use #Bean(name="dummyBean") and the in the #Autowired use the annotation #Qualifier("dummyBean")

Categories