Spring Boot Actuator Custom RestControllerEndpoint with RequestMapping Annotation on class level - java

I have some custom actuator endpoints which should have the same parameters after the endpoint id. Therefore I use the #RestEndpointController annotation to get "full" control over the endpoints via MVC annotations. But I recognized a problem when I use the #RequestMapping annotation on class level on my RestEndpointController class.
My sample implementation:
#Component
#RestControllerEndpoint(id = "tenant")
#RequestMapping("customer/{id}")
public class TenantEndpoint {
#GetMapping
public String getTenantById(#PathVariable("id") String customerId) {
return "Tenant_" + customerId;
}
}
with the following application.properties
management.endpoints.web.exposure.include=health, info, metrics, tenant
and my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
when running this app, there are two endpoints registered in Spring Boot
/actuator/tenant/customer/{id}
/customer/{id}
How can I avoid the second (non actuator) endpoint to be registered?
Or is it a bug of Actuator / Spring-Boot?

Do not use #RequestMapping on class level. You can mention the subsequent path as part of #GetMapping. Below code will register only a single endpoint viz. /actuator/tenant/customer/{id}
#Component
#RestControllerEndpoint(id = "tenant")
public class TenantEndpoint {
#GetMapping("/customer/{id}")
public String getTenantById(#PathVariable("id") String customerId) {
return "Tenant_" + customerId;
}
}

you should try, I didn't check it, bring some feedback in case you test it please.
#Component
#RestControllerEndpoint(id = "tenant")
#RequestMapping("customer")
public class TenantEndpoint {
#GetMapping("/{id}")
public String getTenantById(#PathVariable("id") String customerId) {
return "Tenant_" + customerId;
}
}

Related

How to run tests in a Multi Module Springboot project?

I am currently experimenting with Multi Modules for Springboot and I would to know what are the good or best practices when running tests within different modules that do not contain #SpringBootApplication annotation but have structures or beans like #RestController without errors such as:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.example.mavenmultimodule.controllers.AdditionController required a bean of type 'com.example.mavenmultimodule.services.SumService' that could not be found.
Action:
Consider defining a bean of type 'com.example.mavenmultimodule.services.SumService' in your configuration.
Failed test:
package com.example.mavenmultimodule.controllers;
imports...
#SpringBootTest(classes = AdditionController.class)
#AutoConfigureMockMvc
class AdditionControllerTest {
#Mock
private SumService sumService;
#Autowired
private MockMvc mockMvc;
#Test
public void shouldReturn5() throws Exception {
SumModel s = new SumModel();
s.setN1(2.0);
s.setN2(3.0);
Gson gson = new Gson();
String json = gson.toJson(s);
when(sumService.sum(s)).thenReturn(5.0);
MvcResult result = this.mockMvc.perform(
post("/sum")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
)
.andExpect(status().isOk())
.andReturn();
assertEquals(5, result.getResponse());
}
}
I have the following structure:
Parent
- pom.xml
- addition
- pom.xml
- src
- main
- test
- subtraction
- pom.xml
- src
- main
- test
- application
- pom.xml
- src
- main
- test
Where application/src/main/MavenMultiModuleApplication contains the following code:
package com.example.mavenmultimodule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication(scanBasePackages = "com.example.mavenmultimodule")
public class MavenMultiModuleApplication {
public static void main(String[] args) {
SpringApplication.run(MavenMultiModuleApplication.class, args);
}
}
The parent pom file contains the following:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<groupId>com.example</groupId>
<artifactId>mavenmultimodule</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mavenmultimodule</name>
<description>mavenmultimodule</description>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<modules>
<module>addition</module>
<module>subtraction</module>
<module>application</module>
</modules>
</project>
The application pom file contains the following:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- Parent for the dependencies -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>application</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Custom dependencies -->
<dependency>
<groupId>com.example</groupId>
<artifactId>addition</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>subtraction</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
And both addition and subtraction module contain pom contains:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- Parent for the dependencies -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>subtraction</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
</project>
Link to the repository in question on Github:
https://github.com/filipe-costa/maven-multi-module
Link to the failing test:
https://github.com/filipe-costa/maven-multi-module/blob/main/addition/src/test/java/com/example/mavenmultimodule/controllers/AdditionControllerTest.java
I ended up figuring it out thanks to Igor.
I not only had to add #MockBean to the service being mocked but also the following annotations to the testing class #WebMvcTest(controllers = AdditionController.class) and #ContextConfiguration(classes = AdditionController.class).
#WebMvcTest(controllers = AdditionController.class)
#ContextConfiguration(classes = AdditionController.class)
class AdditionControllerTest {
ObjectMapper objectMapper = new ObjectMapper();
#MockBean
private SumService sumService;
#Autowired
private MockMvc mockMvc;
#Test
public void shouldReturn5() throws Exception {
Double expectedValue = 5.0;
SumModel s = new SumModel();
s.setN1(2.0);
s.setN2(3.0);
String json = objectMapper.writeValueAsString(s);
given(this.sumService.sum(any())).willReturn(expectedValue);
this.mockMvc.perform(
post("/sum")
.accept(MediaType.APPLICATION_JSON_VALUE)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(json)
)
.andExpect(status().isOk())
.andExpect(content().string(expectedValue.toString()));
}
}
I am still unsure if it is a good practice to not have a SpringBootApplication annotated class in the addition module.
It works for what I needed to understand, I hope this might help others as well.

Whitelabel Error Page, rest urls not executed in springboot

new to spring boot application development. I ran the application as java application and got the below error. THe application is deployed successfully , I don't know why this error is rendered ... beating my head.. thank you for your help in advance.
Whitelabel Error Page This application has no explicit mapping for
/error, so you are seeing this as a fallback. Sat Jul 13 21:37:31 IST
2019 There was an unexpected error (type=Not Found, status=404). No
message available
tried solutions given on stack overflow but no help. could you please help me if anywhere I do wrong here.
package com.cpi.poc.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cpi.poc.service.IService;
#RestController
#RequestMapping(value ="/test")
#ComponentScan(basePackages = "com.cgi.poc")
public class TestController {
#Autowired
IService service;
#RequestMapping(value = "/greet" , method = RequestMethod.GET)
public String testService(){
String result = service.greet();
return result;
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.21.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cgi.poc</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Check whether you have class :
#SpringBootApplication
#ComponentScan("com.cgi.poc")
#ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
No need to put component scan on controller if you have the above class.
Verify by using lsof command that your java service is running on the port on not.

#cacheable not working with spring boot. Using ehcache3

*Ehcache3 not working with spring boot - I tried out with approach given below. Spring boot never caches the value mentioned in the component.It is getting called n - no of times no matter the cache is enable or not. In the logs it shows cache is added to cache manager but thats not the case here
ehcache.xml
<ehcache:config>
<ehcache:cache-template name="myDefaultTemplate">
<ehcache:expiry>
<ehcache:none/>
</ehcache:expiry>
</ehcache:cache-template>
<ehcache:cache alias="customer" uses-template="myDefaultTemplate">
<ehcache:key-type>java.lang.Long</ehcache:key-type>
<ehcache:value-type>com.controller.Customer</ehcache:value-type>
<ehcache:expiry>
<ehcache:tti unit="seconds">30</ehcache:tti>
</ehcache:expiry>
<ehcache:heap unit="entries">200</ehcache:heap>
</ehcache:cache>
</ehcache:config>
In my pom.xml i have the following configurations -
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.6.2</version>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application.java which starts spring boot app
#SpringBootApplication
#ComponentScan(basePackages = {"com.service"})
#EnableCaching
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
Component class for caching -
#Component
public class CustomerService {
#Cacheable(cacheNames = "customer",key="#id")
public Customer getCustomer(final Long id){
System.out.println("Returning customer information for customer id
{}
"+id);
Customer customer = new Customer();
customer.setCustomerId(id);
customer.setFirstName("Test");
customer.setEmail("contact-us#test.com");
return customer;
}
}
I tried with couple of approaches by adding component scan in the application
but didn't worked out.
Spring boot starts and it shows cache has been added to cache manager.
I got it working by changing from #Component to #Service. I don't understand why caching is not working under component and works in service layer
If you want to add Caching annotation at the Repository layer then just remove #Repository Annotation, If you want to add Caching at Service Layer then use #Service Annotation instead of #Component Annotation.

Class is not found from jar from dependency jar

I have some project trying to build a microservices architecture. Some of the projects are used producing jar files (I refer these projects as "library projects".) for the callable microservices. One of these microservices are responsible for user/customer registration and lookup. All the data is persisted in a Cassandra cluster. One of the library projects are responsible for providing various Cassandra based services/value objects, etc...
In the microservice pom file, I include the jar produced by the library
project. It compiles, but when I start the customer service the classes from that jar are not found.
***************************
APPLICATION FAILED TO START
***************************
Description:
Field repository in com.besztercekk.tao.customer.handler.PostUserHandler required a bean of type 'com.besztercekk.tao.cassandra.repository.ReactiveUserRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.besztercekk.tao.cassandra.repository.ReactiveUserRepository' in your configuration.
Here are some code snippets, but I can attach anything else you need.
This is the pom file for the microservice. The class what is not found is in this dependency: tao-elszamolas-cassandra.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>tao-elszamolas-customer-service</artifactId>
<packaging>jar</packaging>
<name>tao-elszamolas-customer-service</name>
<description>TAO elszamolas customer backend service</description>
<parent>
<groupId>com.besztercekk.tao</groupId>
<artifactId>tao-elszamolas-spring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<!-- Spring Cloud Eureka client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Spring Cloud config client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<!-- Webflux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Reactive cassandra -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra-reactive</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.1-jre</version>
</dependency>
<!-- TAO elszamolas dependencies -->
<dependency>
<groupId>com.besztercekk.tao</groupId>
<artifactId>tao-elszamolas-cassandra</artifactId>
</dependency>
<dependency>
<groupId>com.besztercekk.tao</groupId>
<artifactId>tao-elszamolas-jwt</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
This is the pom file for the project what contains the missing class:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>tao-elszamolas-cassandra</artifactId>
<packaging>jar</packaging>
<name>tao-elszamolas-cassandra</name>
<description>TAO elszámolás Spring alapú több projektben használt komponensek gyűjtő projektje</description>
<parent>
<groupId>com.besztercekk.tao</groupId>
<artifactId>tao-elszamolas-spring</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<!-- Reactive cassandra -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra-reactive</artifactId>
</dependency>
</dependencies>
</project>
Here the class where the error is coming from:
#Component
#Validator(UserDataValidator.class)
public class PostUserHandler extends AbstractValidationHandler<User, ChainableValidator> {
#Autowired
private ReactiveUserRepository repository;
#Autowired
private PasswordEncoder passwordEncoder;
public PostUserHandler() {
super(User.class);
}
#Override
protected Mono<ServerResponse> processRequest(User body, ServerRequest request) {
return repository.save(enrichUser(body, UUIDs.random().toString()))
.flatMap(updatedUser -> {
sendRegistrationCode();
return ok(updatedUser);
})
.onErrorResume(IllegalArgumentException.class, e -> ServerResponse.badRequest().build())
.switchIfEmpty(ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
}
#Override
protected Mono<User> extractContent(ServerRequest request) {
return request.bodyToMono(User.class);
}
private void sendRegistrationCode() {
//TODO: Send Kafka message to email component
}
private Mono<ServerResponse> ok(User c) {
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromPublisher(Mono.just(c), User.class));
}
private User enrichUser(User user, String activationCode) {
return User.builder()
.authorities(user.getAuthorities())
.email(user.getEmail())
.enabled(user.isEnabled())
.firstName(user.getFirstName())
.id(UUIDs.timeBased())
.lastName(user.getLastName())
.middleName(user.getMiddleName())
.password(passwordEncoder.encode(user.getPassword()))
.registrationTime(LocalDateTime.now())
.passwordExpiryTime(LocalDateTime.now())
.roles(user.getRoles())
.username(user.getUsername())
.accountExpired(false)
.accountLocked(false)
.activationCode(activationCode)
.build();
}
}
Any help would be appreciated!
UPDATE (SOME EXTRA INFO ADDED):
Here is the main class containing the component scan.
#SpringBootApplication
#EnableEurekaClient
#ComponentScan(basePackages = {"com.besztercekk.tao.customer", "com.besztercekk.tao.cassandra"})
public class CustomerBackendApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerBackendApplication.class, args);
}
}
Here is the repository class:
package com.besztercekk.tao.cassandra.repository;
import java.util.UUID;
import org.springframework.data.cassandra.repository.ReactiveCassandraRepository;
import org.springframework.stereotype.Component;
import com.besztercekk.tao.cassandra.model.User;
import reactor.core.publisher.Mono;
/**
* This interface provides reactive {#link User} services.
*/
public interface ReactiveUserRepository extends ReactiveCassandraRepository<User, UUID> {
Mono<User> findByUsername(String username);
Mono<User> findByEmail(String email);
}
Also tried to add #Component and #Repository annotations to this interface, just to see its effect. :-)
My other idea was add the bean programatically to the context after restart. But this is just an interface, so not sure if it works out at all.
The third idea was wrap this interface into a service class and that is easy to add programatically.
But I really want it to be added automatically, without writing code.
Try adding the following annotation to any of the #Configuration classes:
#EnableReactiveCassandraRepositories
#Configuration
class MyConfiguration() {
//code
}
The above code enables spring to automatically scan and create the default implementation bean for your interface ReactiveUserRepository .
Also annotate the interface like :
#Repository
public interface ReactiveUserRepository extends ReactiveCassandraRepository<User, UUID> {
Mono<User> findByUsername(String username);
Mono<User> findByEmail(String email);
}
For more details read :
https://dzone.com/articles/reactive-streams-with-spring-data-cassandra
Also, if you would like more details on the annotations read a similar post :
how annotation #Repository in java spring work?

Spring boot consider defining a bean of type, component scan not working

I am trying to follow the below tutorial:
https://dzone.com/articles/spring-boot-jpa-hibernate-oracle
My project structure is as follows:
My pom is as below:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.nuril.work</groupId>
<artifactId>SpringBootHiberate</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
When I run the Application class as shown:
#SpringBootApplication
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class Application implements CommandLineRunner{
#Autowired
SoccerService soccerService;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... arg0) throws Exception {
soccerService.addBarcelonaPlayer("Xavi Hernandez", "Midfielder", 6);
List<String> players = soccerService.getAllTeamPlayers(1);
for(String player : players)
{
System.out.println("Introducing Barca player => " + player);
}
}
}
I get the below error:
Description:
Field playerRepository in com.nuril.work.service.SoccerServiceImpl required a bean of type 'com.nuril.work.repository.PlayerRepository' that could not be found.
Action:
Consider defining a bean of type 'com.nuril.work.repository.PlayerRepository' in your configuration.
I looked at other answers and they suggested to add #ComponentScan annotation.
I added the following
#SpringBootApplication
#ComponentScan("com.nuril.work.repository")
#ComponentScan("com.nuril.work.service")
However I am still getting the same error, what could be the reason for this?
Try to add #EnableJpaRepositories(basePackages="com.nuril.work.repository") onto Application class.
See docs: https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/config/EnableJpaRepositories.html
Also, check if your repositories have #Repository annotation.

Categories