con not invoke "" because this."" is null (or) Cannot invoke "CustomerRepository.findAll()" because "this.customerRepository" is null - spring

When we get error syaing that - can not invoke "" because this."" is, how to resolve this?
For e.g.,
Cannot invoke "com.saran.sprndatajpa.config.CustomerRepository.findAll()" because "this.customerRepository" is null
Thanks.

This error occur as the required bean is not autowired.
In this case, if we autowire customerRepository, the error will resolve.
#Autowired
CustomerRepository customerRepository ;
Thanks.

Related

#WebMvcTest with #Import does not work. Test context always asks for #Repository beans

Using Spring Boot 2.7.3 I can not create a simple integration test for my API using #WebMvcTest.
Here is my setup:
// GameServerApplicationTests.kt
#SpringBootTest
class GameServerApplicationTests {
#Test
fun contextLoads() { }
}
// CraftService.kt
#Service
class CraftService {
fun getAll(): List<String> {
return listOf("foo", "bar")
}
}
// CraftApiTest.kt
#WebMvcTest
#Import(value = [CraftService::class])
class CraftApiTest {
#Autowired
private lateinit var testRestTemplate: TestRestTemplate
#Test
fun `should do accept craft all endpoint`() {
val response = testRestTemplate.getForEntity("/craft/all", String::class.java)
assertThat(response.statusCode).isEqualTo(HttpStatus.OK)
}
}
When I run the test I see this exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'itemRepository' defined in com.gameserver.item.ItemRepository defined in #EnableJpaRepositories declared on GameServerApplication: Cannot create inner bean '(inner bean)#3fba233d' 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)#3fba233d': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
I have no idea why it is looking for the itemRepository bean at all. I never asked for that.
I then added this
#WebMvcTest
#ComponentScan(excludeFilters = [ComponentScan.Filter(Repository::class)]) // <<
#Import(value = [CraftService::class])
Which resulted in this exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'playerRepository' defined in com.gameserver.player.PlayerRepository defined in #EnableJpaRepositories declared on GameServerApplication: Cannot create inner bean '(inner bean)#30c1da48' 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)#30c1da48': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
Which confuses me even more. I explictly excluded all #Repository beans - but it just skipped ItemRepository and then asked for PlayerRepository now.
I am totally lost and have no idea why I am not able to setup a simple integration test for my API endpoint.
EDIT #1:
Other tests run just fine:
EDIT #2:
I tried to use a #Configuration bean for #Import.
// CraftApiTestConfiguration
#Configuration
class CraftApiTestConfiguration {
#Bean
fun getCraftService(): CraftService {
return CraftService()
}
}
// CraftApiTest.kt
#WebMvcTest
#Import(CraftApiTestConfiguration::class)
class CraftApiTest { // ... }
That did not help either. It just gave me the second exception mentioned above (the one asking for playerRepository)
I'll try to answer although without seeing the actual code it might not be correct.
So #WebMvcTest loads a "slice" of your application with all the beans annotated with #RestControllers. It doesn't load #Service or #Repository annotated beans.
When you run the test with #WebMvcTest annotation it will load all the controllers, and if, by accident the controller references others than the reference on the service (here I can't say for sure what it is), you might end up loading the stuff that you don't actually need.
Now when you use #WebMvcTest there are two things you can/should do:
Work with MockMvc instead of rest template that queries a web server, its not a full-fledged web layer test anyway.
Try using #WebMvcTest with your controller only:
#WebMvcTest(CraftApisController.class)
Also instead of injecting the real implementation of service, you can use #MockBean so that the real service implementation will be covered by a regular unit test (without spring at all, just plain JUnit/Mockito) and this test could check that your annotations are defined correctly

Mockito.verify() in Groovy causing ambiguous method error for a Spring #MockBean

I am trying to verify that a method was called on a Spring #MockBean:
Mockito.verify(rabbit).convertAndSend(
Mockito.isA(String.class),
Mockito.isA(String.class),
Mockito.isA(Object.class)
)
I am doing this in a Spock test, and getting the following error:
Caused by: groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method org.springframework.amqp.rabbit.core.RabbitTemplate$MockitoMock$2020468097#convertAndSend.
Cannot resolve which method to invoke for [null, null, null] due to overlapping prototypes between:
[class java.lang.String, class java.lang.Object, interface org.springframework.amqp.core.MessagePostProcessor]
[class java.lang.Object, interface org.springframework.amqp.core.MessagePostProcessor, class org.springframework.amqp.rabbit.connection.CorrelationData]
... 1 more
Is there a better way to use Mockito syntax to point it to the particular method?

Creating A pointcut using args designator with no types results in BeanCurrentlyInCreationException

Using Spring AOP, when attempting to create a Pointcut using the designator args while not providing any types results in a series of exceptions starting with BeanCurrentlyInCreationException
The Example
object _001_Spring_AOP_Pointcut_Args_NoArgs {
open class BeanA {
open fun m() {
println("BeanA#m()")
}
}
#Aspect
class AspectA {
#Pointcut("args()")
private fun pc_noArgs() = Unit
#After("sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs.AspectA.pc_noArgs()")
private fun ac_noArgs() = println("ac_noArgs")
}
#Configuration
#EnableAspectJAutoProxy(proxyTargetClass = true)
open class Config {
#Bean
open fun beanA(): BeanA = BeanA()
#Bean
open fun aspectA(): AspectA = AspectA()
}
fun runJava() {
AnnotationConfigApplicationContext(Config::class.java)
}
}
The Run Method
#Test
fun test_run() {
_001_Spring_AOP_Pointcut_Args_NoArgs.runJava()
}
The Exception Summary
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanA' defined in sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs$Config: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs$BeanA]: Factory method 'beanA' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'aspectA' defined in sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs$Config: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs$AspectA]: Factory method 'aspectA' threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'aspectA': Requested bean is currently in creation: Is there an unresolvable circular reference?
args() vs. execution(* *())
This is an unusual way of intercepting all methods without parameters. I would rather make it more explicit and use execution(* *()) instead. If you ever migrate from Spring AOP to AspectJ, you will notice that args() matches all kinds of pointcuts there, e.g. call, initialization, preinitialization, staticinitialization, get and constructor calls/executions without parameters.
Pointcut scoping
Here in Spring AOP your problem might be another one, though: Your pointcut is too broad. It matches many joinpoints in Spring beans, also in Spring or third-party classes themselves. So you want to limit the scope of your pointcut, e.g. something like
execution(* *()) && within(my.own.package.**)
When to (not) use fully qualified class names in pointcuts
BTW, if your pointcut is defined in the very same class as the advice using it, it should not be necessary to use a fully qualified class name, i.e. instead of
#After("sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs.AspectA.pc_noArgs()")
you could use
#After("pc_noArgs()")
Inline pointcuts
If you have no plans to re-use the same pointcut in other advices, just get rid of #Pointcut and define an inline pointcut such as
#After("execution(* *()) && within(my.own.package.**)")
Advices should be public
While it is OK to define the #Pointcut method as private if you do not refer to it from other classes, the #After advice should be public. It might work in Spring AOP, but is against conventions. Again, if you ever migrate to AspectJ, you will even get a compile error because an AspectJ advice must be public.
The code shared fails with the following exception -
org.springframework.beans.factory.BeanCurrentlyInCreationException
, when the pointcut expression has a scope within the package the aspect class resides.
Example:
Fully qualified names for the beans :
rg.spring.boot.AspectA
rg.spring.boot.bean.BeanA
And a pointcut expression like the following would fail:
#Pointcut("args() && within(rg.spring.boot..*)")
whereas, the following pointcut expression succeeds :
#Pointcut("args() && within(rg.spring.boot.bean..*)")
The exception, as per me, is because the pointcut targets framework methods of the aspect during initialization. To resolve the exception, you may move the bean to a specific package and fine tune the scope of the pointcut expression for that package.

Parse LocalTime string inside the #Value attribute

My environment variable is a string with time 23:30 In my String Boot application I'd like to parse it automatically and set it the result to variable.
I tried like this
#Value("#{ java.time.LocalTime.parse('${NIGHT_START_TIME}')}")
private LocalTime NIGHT_START_TIME;
IntelliJ shows the error
Cannot resolve variable 'java'
Here is log
Unsatisfied dependency expressed through field 'NIGHT_START_TIME';
nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'LocalTime' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
If I read variable like this I see that value is correct
#Value("${NIGHT_START_TIME}")
private String NIGHT_START_TIME;
Any ideas how to make it work?
Try this
#Value("#{ T(java.time.LocalTime).parse('${NIGHT_START_TIME}')}")
private LocalTime NIGHT_START_TIME;
The way you reference a class is using T.
Check the documentation.
Have checked at Spring Boot 2.2.6.RELEASE:
application.yml
NIGHT_START_TIME: '23:30'
Service
#Value("${NIGHT_START_TIME}")
private LocalTime NIGHT_START_TIME;
Work perfect without any "knee bends":)

Dependency Injection in JSR-303 ConstraintValidator

I have the same problem that the guy from this thread has.
More precisely I get the following error, when trying to inject a bean in my custom validator that implements CustomValidator interface (it's a NPE when accessing the bean i wanted to inject):
javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.
at org.hibernate.validator.internal.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.java:294)
at org.hibernate.validator.internal.engine.ConstraintTree.validateConstraints(ConstraintTree.java:164)
at org.hibernate.validator.internal.engine.ConstraintTree.validateConstraints(ConstraintTree.java:125)
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:86)
...
Caused by: java.lang.NullPointerException
Do you have a solution for this? Maybe an example? Because I tried the solutions offered on the other thread and nothing worked.
Any help is appreciated. Thanks.
You should not create validator factory on your own (Validation.buildDefaultValidatorFactory()) if you want to use Spring based constraint validators.
You should let Spring autowire correct factory to your bean:
#Controller
public class MyController {
#Autowired
private ValidatorFactory validatorFactory;
// ... handler methods
}

Resources