#Repository class not getting Autowired in my test class - spring-boot

I have DAO marked with #Repository annotation in the main folder. I need to access this DAO in my test class. I'm using #Autowire for this but the DAO object is throwing a null pointer exception.
Please help as I'm relatively new to Spring boot

Related

Spring Boot JPA : Autowired JPA repository extends CrudRepository is null

I am not getting repository bean in service class.
Your interface ActorRepository must be annotated with #Repository.

Why do we need to annotate the Service class with #Transactional in Spring Data JPA

In a spring boot app, we have user-defined repository interface that extends JpaRepository.
JpaRepository in turn is has an implementation class SimpleJpaRepository.
SimpleJPARepository has 2 annotations on it
#Transactional
#Repository
So we can skip these 2 annotations on our user-defined repository interface that extends JpaRepository.
Then why do we need to explicitly add #Transactional over service class which is also using our user-defined repository object only?
The point of having the Transactional annotation is so that everything in the annotated method occurs within the same unit of work and either everything succeeds or everything fails. Putting Transactional only on each repository means each repository can have its own transaction, and the second one failing doesn't rollback the first one.
You can have nontransactional methods on a service, or every method so annotating a class as a Service doesn't mean spring can assume everything is transactional.
This is a has vs is problem.
An object can be Transactional, or have a member object that is Transactional.
If the object has a member object that is Transactional, it is not automatically Transactional itself.
Object A contains Object B which is Transactional, that does not make Object A Transactional.

Should we use #Component on #Entity class in Spring boot

Well i am a newbie in spring boot. I was working on a project where I needed to #Autowired my Entity in a controller class. But I ended up with error:
Field repository in abc required a bean of type 'xyz' that could not be found.
But it solved after adding #Component in Entity class.
So my questions are:
Why Spring boot was not scanning my Entity class as it was under #SpringBootApplication declaration?
When and where we should use #Component annotation in our application?
Use #Component to flag your Pojo as Spring Bean, so that you inject it into other beans with #Autowired
Use #Entity to flag your Pojo as JPA or Spring Data managed bean to read or write it to a database

Spring Annotation #WebMvcTest does not work in an app that has Jpa repositories

I have a Spring App that uses JPA repositories (CrudRepository interfaces). When I try to test my controller using the new Spring test syntax #WebMvcTest(MyController.class), it fails coz it tries to instantiate one of my service class that uses JPA Repository, does anyone has any clues on how to fix that? The app works when I run it.
Here is the error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.myapp.service.UserServiceImpl required a bean of type 'com.myapp.repository.UserRepository' that could not be found.
Action:
Consider defining a bean of type 'com.myapp.repository.UserRepository' in your configuration.
According to the doc
Using this annotation will disable full auto-configuration and instead apply only configuration relevant to MVC tests (i.e. #Controller, #ControllerAdvice, #JsonComponent Filter, WebMvcConfigurer and HandlerMethodArgumentResolver beans but not #Component, #Service or #Repository beans).
This annotion only apply on the Spring MVC components.
If you are looking to load your full application configuration and use MockMVC, you should consider #SpringBootTest combined with #AutoConfigureMockMvc rather than this annotation.
I was able to unit test a Rest Controller by implementing junit 5 and using #SpringJUnitConfig along with #WebMvcTest. I am using Spring Boot 2.4.5 and this is my example:
#SpringJUnitConfig
#WebMvcTest(controllers = OrderController.class)
class OrderControllerTest {
#Autowired
private MockMvc mockMvc;
// This is a Mock bean of a Spring Feign client that calls an external Rest Api
#MockBean
private LoginServiceClient loginServiceClient;
// This is a Mock for a class which has several Spring Jpa repositories classes as dependencies
#MockBean
private OrderService orderService;
#DisplayName("should create an order")
#Test
void createOrder() throws Exception {
OrderEntity createdOrder = new OrderEntity("123")
when(orderService.createOrder(any(Order.class))).thenReturn(createdOrder);
mockMvc.perform(post("/api/v1/orders").contentType(MediaType.APPLICATION_JSON).content("{orderId:123}"))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))TODO: here it will go the correlationId
.andExpect(jsonPath("$.orderId").value("123"));
}
}
Please only use #SpringBootTest when you are implementing integration tests.
I faced this same problem. Using #SpringBootTest and #AutoConfigureMockMvc worked perfectly for me.

#Repository in Spring 4

#Repository
public interface userRepository extends JpaRepository<User, Long> {
}
There are many sites showing this way of creating DAO in Spring 4 using JpaRepository. #Repository also creating instance just like #Component, #Service etc. Container internally beans by using new operator while component scan (using #Component scan annotation) of classes having annotation #Component, #Service etc. Then how container create instance for #Repository as shown above, as it is an interface which is purely abstract and we can't create instance for interface using new operator.
Spring will create a SimpleJpaRepository instance for declared Interfaces that extend JpaRepository.
Note: there is much more magic going on. You can add your own queries via #Query to the interface and Repositories also support transaction management. To achieve that the Repository will be wrapped in a proxy which can intercept and dynamically implement its methods.

Resources