RequestBody is not returning username - SpringBoot - java

I'm making a POST request to authenticate the API that I'm implementing, but I have the following problem:
My username is not being returned:
however, my password is, and I'm not understanding why:
Below I will be sending my source code for better understanding...
Class: AuthController.java
#RestController
#RequestMapping("/auth")
public class AuthController {
#Autowired
AuthenticationManager authenticationManager;
#Autowired
JwtTokenProvider jwtTokenProvider;
#Autowired
UserRepository repository;
#ApiOperation(value = "Authenticate a user by credentials") //Swagger endpoint description
#PostMapping(value="/signin", produces = { "application/json", "application/xml", "application/x-yaml" }, consumes = {
"application/json", "application/xml", "application/x-yaml" })
public ResponseEntity singin(#RequestBody AccountCredentialsVO data) throws Exception {
try {
var username = data.getUserName();
var password = data.getPassword();
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
var user = repository.findByUserName(username);
var token = "";
if(user != null) {
token = jwtTokenProvider.createToken(username, user.getRoles());
}else {
throw new UsernameNotFoundException("Username " + username + " not found!");
}
Map<Object, Object> model = new HashMap<>();
model.put("username", username);
model.put("token", token);
return ok(model);
} catch (Exception e) {
throw new BadCredentialsException("Invalid username/password supplied!");
}
}
}
Class: AccountCredentialsVO.java
public class AccountCredentialsVO implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "username")
private String username;
private String password;
public String getUserName() {
return username;
}
public void setUserName(String userName) {
this.username = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public int hashCode() {
return Objects.hash(password, username);
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AccountCredentialsVO other = (AccountCredentialsVO) obj;
return Objects.equals(password, other.password) && Objects.equals(username, other.username);
}
}
The pom.xml:
<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">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>br.com.andrefilipeos</groupId>
<artifactId>rest-with-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<description>Creating API RESTFul with Spring Boot 2.x</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
</properties>
<dependencies>
<!-- for Spring-boot Support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- for Tests Support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-core</artifactId>
<version>6.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- for XML support-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<!-- for YML or YAML support-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
<!-- for HATEOAS Support -->
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
<!-- for Swagger Support -->
<!-- http://localhost:8080/v2/api-docs -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- it's format all API documentation organized -->
<!-- http://localhost:8080/swagger-ui.html -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- for Security Support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- for Tokens Support -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!-- for Migration support $mvn flyway:migrate -->
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<configuration>
<url>jdbc:mysql://localhost:3306/rest_with_springboot?useTimezone=true&serverTimezone=UTC&useSSL=false</url>
<user>root</user>
<password>admin123</password>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
My POST request:
http://localhost:8080/auth/signin
With XML (application/xml):
<AccountCredentialsVO>
<username>leandro</username>
<password>admin123</password>
</AccountCredentialsVO>
With JSON (application/json):
{
"username":"leandro",
"password":"admin123"
}
And unfortunately with both requests I'm getting the same result of null username!

Related

Basic authentication in Spring Boot

I have added basic authentication in my Rest API. My API is CRUD. I have changed the username and password. When I apply the GET, GET by id parameter and POST, they are working flawlessly but when I call the PUT and DELETE, I get 401 unauthorized. I have checked the username and password for they are correct or no. There is no problem about it. What is the reason about this issue?
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>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xyztq</groupId>
<artifactId>TodoApp2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>TodoApp2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.project.lombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
SecurityConfiguration class
#Configuration
#EnableWebSecurity
public class SecurityConfiguration {
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.httpBasic();
http.formLogin();
http.authorizeHttpRequests().requestMatchers("/todos").authenticated().and()
.csrf().ignoringRequestMatchers("/todos")
.and().authorizeHttpRequests().requestMatchers("/todos/{id}").authenticated().and()
.csrf().ignoringRequestMatchers("/todos/{id}");
return http.build();
}
This is my controller
#RestController
#RequestMapping("/todos")
#AllArgsConstructor
public class TodoController {
private final TodoService todoService;
#GetMapping
public ResponseEntity<List<Todo>> getTodos(#RequestParam(required = false) String title){
return new ResponseEntity<>(todoService.getTodos(title), OK);
}
#GetMapping("/{id}")
public ResponseEntity<Todo> getTodo(#PathVariable String id){
return new ResponseEntity<>(todoService.getTodoById(id), OK);
}
#PostMapping
public ResponseEntity<Todo> createTodo(#RequestBody Todo todo){
return new ResponseEntity<>(todoService.createTodo(todo), OK);
}
#PutMapping("/{id}")
public ResponseEntity<Void> updateTodo(#PathVariable String id,#RequestBody Todo todo){
todoService.updateTodo(id,todo);
return new ResponseEntity<>(OK);
}
#PatchMapping("/{id}")
public ResponseEntity<Void> updateDoneTodo(#PathVariable String id,#RequestBody Todo todo){
todoService.patchTodo(id,todo);
return new ResponseEntity<>(OK);
}
#DeleteMapping("/{id}")
public ResponseEntity<Void> deleteTodo(#PathVariable String id){
todoService.deleteTodo(id);
return new ResponseEntity<>(OK);
}

Java Lambda for spring-cloud version to 3.2.3/3.1.7 org/springframework/boot/ApplicationContextFactory: java.lang.NoClassDefFoundError

I'm trying change version for spring-cloud-function-adapter-aws from 3.0.7.RELEASE to either 3.1.7 or 3.2.3 (as Spring Cloud Function Vulnerability CVE-2022-22963) but getting error as it is not able to find the class
java.lang.NoClassDefFoundError: org/spring framework/boot/ApplicationContextFactory
at org.springframework.cloud.function.context.FunctionalSpringApplication.(FunctionalSpringApplication.java:67)
at org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer.springApplication(AbstractSpringFunctionAdapterInitializer.java:378)
at org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer.initialize(AbstractSpringFunctionAdapterInitializer.java:121)
at org.springframework.cloud.function.adapter.aws.SpringBootStreamHandler.initialize(SpringBootStreamHandler.java:61)
at org.springframework.cloud.function.adapter.aws.SpringBootStreamHandler.handleRequest(SpringBootStreamHandler.java:53)
Caused by: java.lang.ClassNotFoundException:
My Application.java
#ComponentScan
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
FunctionConfiguration.java
#Configuration
public class FunctionConfiguration {
private static Logger logger = LoggerFactory.getLogger(FunctionConfiguration.class);
#Autowired
ActionService service;
#Bean
public Function<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> containerService() {
return value -> {
try {
APIGatewayProxyResponseEvent responseEvent = checkHttpMethod(value);
if (responseEvent != null) {
responseEvent.setBody("Option Method");
return responseEvent;
} else {
return createResponseEvent(value);
}
} catch (Exception e) {
return new APIGatewayProxyResponseEvent().withBody(e.getMessage()).withStatusCode(500)
.withHeaders(createResultHeader(value));
}
};
}
private APIGatewayProxyResponseEvent checkHttpMethod(APIGatewayProxyRequestEvent event) {
APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent();
if (event.getHttpMethod() != null && event.getHttpMethod().equalsIgnoreCase("options")) {
responseEvent.setHeaders(createResultHeader(event));
responseEvent.setStatusCode(200);
return responseEvent;
} else
return null;
}
private APIGatewayProxyResponseEvent createResponseEvent(APIGatewayProxyRequestEvent event) {
APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent();
try {
responseEvent = service.actionMethod(event);
responseEvent.setHeaders(createResultHeader(event));
return responseEvent;
} catch (Exception e) {
logger.error("Error executing method", e);
responseEvent.setHeaders(createResultHeader(event));
responseEvent.setBody(e.getMessage());
responseEvent.setStatusCode(500);
return responseEvent;
}
}
private Map<String, String> createResultHeader(APIGatewayProxyRequestEvent event) {
Map<String, String> resultHeader = new HashMap<>();
resultHeader.put("Content-Type", "application/json");
resultHeader.put("Access-Control-Allow-Headers", "Content-Type");
resultHeader.put("Vary", "Origin");
try {
String origin = event.getHeaders().get("origin");
resultHeader.put("Access-Control-Allow-Origin", origin);
} catch (Exception e) {
logger.error("origin not exist to add");
}
resultHeader.put("Access-Control-Allow-Credentials", "true");
logger.info(" Headers added ");
return resultHeader;
}
}
pom.xml
4.0.0
com.app.lambda
springBootLambda
1.0.3
springBootLambda
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<aws-lambda-java-core.version>1.2.1</aws-lambda-java-core.version>
<spring-cloud-function.version>3.0.7.RELEASE
</spring-cloud-function.version>
<wrapper.version>1.0.17.RELEASE</wrapper.version>
<aws-lambda-java-events.version>2.2.7</aws-lambda-java-events.version>
<aws-java-sdk-s3.version>1.11.792</aws-java-sdk-s3.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-json</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<scope>optional</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-aws</artifactId>
<version>${spring-cloud-function.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>${aws-lambda-java-core.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.672</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-core</artifactId>
<version>1.11.672</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>${aws-lambda-java-events.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>${wrapper.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<finalName>${project.artifactId}-${project.version}</finalName>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>shaded</shadedClassifierName>
</configuration>
</plugin>
</plugins>
</build>
serverless.yml
service: SpringBoot-Lambda
provider:
name: aws
runtime: java8
region: us-east-1
memory: 2048
timeout: 40
spring:
jpa:
hibernate.ddl-auto: update
generate-ddl: true
show-sql: true
jar file that will be uploaded and executed on AWS
package:
artifact: target/{project.artifactId}-${project.version}.jar
#define Lambda function
functions:
createMethod:
handler: org.springframework.cloud.function.adapter.aws.SpringBootStreamHandler
events: # api gateway
- http:
path: pass
method: post
cors: true
environment: # environment variables
FUNCTION_NAME: SpringBoot-Lambda
You need to upgrade Spring Boot as well. You are using 2.3.0 and ApplicationContextFactory was added in 2.4, but 2.4.x is no longer supported.
You should upgrade to Spring Boot 2.5.12 or 2.6.6.

Spring boot 2.2.5 release Getting 404 not found error

I am trying to execute Spring boot application hosted on a tomcat server online. The issue is when I try to get, delete or post data, a user controller it generates this message.
{
"timestamp": "2021-01-24T06:45:42.144+00:00",
"status": 404,
"error": "Not Found",
"message": "",
"path": "/tool/api/v1/users"
}
the weird issue is that when I run the server locally http://localhost:8080/api/v1/users I get data
but when I try hosting the war file and hitting the endpoint http://31.134.12.356:9080/tool/api/v1/usersi end up with the error above.
My Users Controller
#RequestMapping("/api/v1")
#RestController
public class UserController {
#Autowired
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
#GetMapping("/users")
public Iterable<User> getAllUsers() {
return userRepository.findAll();
}
#GetMapping("/users/{id}")
public User getUserById(#PathVariable("id") String id) {
return userRepository.findById(id).get();
}
#GetMapping("/users/{username}")
public User getUserByUsername(#PathVariable("username") String username) {
return userRepository.findByUsername(username).get();
}
#PostMapping(value = "/users")
public ResponseEntity<Object> saveUser(#RequestBody SaveUserRequest userRequest) {
//save user details
User user = new User(userRequest.getUsername(),
userRequest.getDisplayName(), userRequest.getEmail(), userRequest.getIdentityProvider());
Set<String> strRoles = userRequest.getRole();
Set<Role> roles = new HashSet<>();
if (strRoles == null) {
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
.orElseThrow(() -> new RuntimeException("Role is not found."));
roles.add(userRole);
} else {
strRoles.forEach(role -> {
switch (role) {
case "admin":
Role adminRole = roleRepository.findByName(ERole.ROLE_ADMIN)
.orElseThrow(() -> new RuntimeException("Role is not found."));
roles.add(adminRole);
break;
case "mod":
Role modRole = roleRepository.findByName(ERole.ROLE_MODERATOR)
.orElseThrow(() -> new RuntimeException("Role is not found."));
roles.add(modRole);
break;
default:
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
.orElseThrow(() -> new RuntimeException("Role is not found."));
roles.add(userRole);
}
});
}
user.setRoles(roles);
user.setId(java.util.UUID.randomUUID().toString());
user.setLastLoggedOn(new Date());
userRepository.save(user);
return ResponseEntity.ok(user);
}
}
The weird issue is that I have other endpoints and they are working fine, the users rest api is the one not being found. I have added tool in the api as it is the name of the war file, I have multiple war files running on the tomcat.
ServletInitializer
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MonitoringToolApplication.class);
}
}
Main class
#SpringBootApplication
#ComponentScan({ "com.example.tool.demo.controller"})
#EntityScan(basePackages = "com.example.tool.demo.model")
public class MonitoringToolApplication {
public static void main(String[] args) {
SpringApplication.run(MonitoringToolApplication.class, args);
}
}
my pom file
<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.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.tool</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Example</name>
<description>example</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!-- <scope>provided</scope>-->
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>8.2.2.jre8</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application.properties file
#Example Tool connection string
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://localhost;databaseName=example_tools
spring.datasource.username=sa
spring.datasource.password= user2k!!__
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.SQLServer2012Dialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql = true
Please help me out with the issue. Many thanks in advance.
When deploying the project on the server side, exclude the embedded tomcat in the pom.xml file
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>

Spring Data Neo4j - findById method throws an invalid query exception after upgrading to Spring Boot 2

I have been working on a micro-service created using Spring Boot with Neo4j as the database. The two relevant entities within it Product and AccessoryRelation are thus:
#NodeEntity
#QueryEntity
public class Product extends AbstractNeo4jEntity {
#Index(primary = true, unique = true)
private String productId;
#Transient
private String market;
#JsonIgnore
#Relationship(type = "HAS_ACCESSORY")
private Set<AccessoryRelation> relations = new HashSet<>();
public Product() {
}
public Product(final String productId) {
this.productId = productId;
}
public String getProductId() {
return productId;
}
public String getMarket() {
return market;
}
public void setMarket(final String market) {
this.market = market;
}
public Set<AccessoryRelation> getRelations() {
return new HashSet<>(relations);
}
public void addAccessory(final Product accessory) {
Assert.notNull(accessory, "Accessory product can not be null");
Assert.hasText(accessory.getProductId(),
"Accessory product should have a valid identifier");
Assert.hasText(accessory.getMarket(),
"Accessory product should be available atleast in one market");
Assert.isTrue(!this.equals(accessory),
"A product can't be an accessory of itself.");
final AccessoryRelation relation = this.relations.stream() //
.filter(rel -> rel.getAccessory().equals(accessory)) //
.findAny() //
.orElseGet(() -> {
final AccessoryRelation newRelation = new AccessoryRelation(this,
accessory, Sets.newHashSet());
this.relations.add(newRelation);
return newRelation;
});
relation.addMarket(accessory.getMarket());
}
public void removeAccessory(final Product accessory) {
Assert.notNull(accessory, "Accessory product can not be null");
Assert.hasText(accessory.getProductId(),
"Accessory product should have a valid identifier");
Assert.hasText(accessory.getMarket(),
"Accessory product should be available atleast in one market");
final Optional<AccessoryRelation> relation = this.relations.stream() //
.filter(rel -> rel.getAccessory().equals(accessory)) //
.findAny();
if (relation.isPresent()) {
relation.get().removeMarket(accessory.getMarket());
if (relation.get().getMarkets().isEmpty()) {
this.relations.remove(relation.get());
}
}
}
public void removeAccessories() {
this.relations.clear();
}
#Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof Product)) {
return false;
}
final Product product = (Product) obj;
return new EqualsBuilder() //
.append(getProductId(), product.getProductId()) //
.isEquals();
}
#Override
public int hashCode() {
return new HashCodeBuilder() //
.append(getProductId()) //
.toHashCode();
}
#Override
public String toString() {
return new ToStringBuilder(this) //
.append("ProductId", getProductId()) //
.toString();
}
}
#RelationshipEntity(type = "HAS_ACCESSORY")
public class AccessoryRelation extends AbstractNeo4jEntity {
#StartNode
private Product product;
#EndNode
private Product accessory;
private Set<String> markets = new HashSet<>();
public AccessoryRelation() {
}
public AccessoryRelation(final Product product, final Product accessory,
final Set<String> markets) {
this.product = product;
this.accessory = accessory;
this.markets = markets;
}
public Product getProduct() {
return product;
}
public void setProduct(final Product product) {
this.product = product;
}
public Product getAccessory() {
return accessory;
}
public void setAccessory(final Product accessory) {
this.accessory = accessory;
}
public Set<String> getMarkets() {
return new HashSet<>(markets);
}
public void addMarket(final String market) {
this.markets.add(market);
}
public void removeMarket(final String market) {
this.markets.remove(market);
}
#Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof AccessoryRelation)) {
return false;
}
final AccessoryRelation relation = (AccessoryRelation) obj;
return new EqualsBuilder() //
.append(getProduct(), relation.getProduct()) //
.append(getAccessory(), relation.getAccessory()) //
.isEquals();
}
#Override
public final int hashCode() {
return new HashCodeBuilder() //
.append(getProduct()) //
.append(getAccessory()) //
.toHashCode();
}
#Override
public String toString() {
return new ToStringBuilder(this) //
.append("Product", getProduct()) //
.append("Accessory", getAccessory()) //
.append("Markets", getMarkets()) //
.toString();
}
}
For JUnit test cases I am using nosqlunit-neo4j version 1.0.0-rc.5 and an embedded databsase.
Now I have the findById(productId) method which would return the Product along with the associated AccessoryRelation objects. However, after upgrading to Spring Boot 2, this method does not work. It throws an exception thus:
org.springframework.data.neo4j.exception.UncategorizedNeo4jException:
Error executing Cypher; Code: Neo.ClientError.Statement.InvalidSyntax;
Description: Invalid input '|': expected whitespace, comment, a
relationship pattern, '.', node labels, '[', "=~", IN, STARTS, ENDS,
CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>',
"<=", ">=", AND, XOR, OR, ',' or ']' (line 1, column 113 (offset:
112))
"MATCH (n:`Product`) WHERE n.`productId` = { id } WITH n RETURN n,[ [
(n)-[r_h1:`HAS_ACCESSORY`]->(p1:`Product`) | [ r_h1, p1 ] ] ]"
^; nested exception is org.neo4j.ogm.exception.CypherException: Error
executing Cypher; Code: Neo.ClientError.Statement.InvalidSyntax;
Description: Invalid input '|': expected whitespace, comment, a
relationship pattern, '.', node labels, '[', "=~", IN, STARTS, ENDS,
CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>',
"<=", ">=", AND, XOR, OR, ',' or ']' (line 1, column 113 (offset:
112))
"MATCH (n:`Product`) WHERE n.`productId` = { id } WITH n RETURN n,[ [
(n)-[r_h1:`HAS_ACCESSORY`]->(p1:`Product`) | [ r_h1, p1 ] ] ]"
By the looks of it, it is treating the '|' character as an invalid character within the query. However, when I run the same query in a neo4 3.4.9 instance on the browser, it works fine. No syntax errors on that one. The application has a default neo4j version of 2.3.3 which coming from the nosqlunit dependency. I have tried including neo4j 3.4.9 dependencies in my pom, but that creates a whole set of new problems.
The following is 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
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-
8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<project.build.itDirectory>src/it/java</project.build.itDirectory>
<neo4j-cypher-dsl.version>2.3-RELEASE</neo4j-cypher-dsl.version>
<querydsl.version>4.1.4</querydsl.version>
<querydsl-apt.version>1.1.3</querydsl-apt.version>
<cglib.version>2.2.2</cglib.version>
<spring-cloud.version>Finchley.RC2</spring-cloud.version>
</properties>
<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>
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>${cglib.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-lucene3</artifactId>
<version>${querydsl.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<!-- This jar is used by CypherQueryDSL at runtime. If its not present
in classpath then java.lang.ClassNotFoundException: org.apache.lucene.search.Query
error is thrown -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>3.6.2</version>
</dependency>
<dependency>
<groupId>com.consol.citrus</groupId>
<artifactId>citrus-core</artifactId>
<version>2.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.consol.citrus</groupId>
<artifactId>citrus-http</artifactId>
<version>2.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.consol.citrus</groupId>
<artifactId>citrus-java-dsl</artifactId>
<version>2.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-cypher-dsl</artifactId>
<version>${neo4j-cypher-dsl.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>com.lordofthejars</groupId>
<artifactId>nosqlunit-neo4j</artifactId>
<version>1.0.0-rc.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.openpojo</groupId>
<artifactId>openpojo</artifactId>
<version>0.8.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>2.1.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-embedded-driver</artifactId>
<version>3.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-all</artifactId>
<version>6.0_ALPHA</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>product-accessory-service</finalName>
<plugins>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>${querydsl-apt.version}</version>
<dependencies>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
</dependencies>
<configuration>
<processor>com.querydsl.apt.QuerydslAnnotationProcessor</processor>
</configuration>
<executions>
<execution>
<id>add-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/querydsl</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
Has anyone encountered a similar issue before? Could anyone please help me out in resolving this? Thanks in advance.

Spring field required a bean of type that could not be found

I'm trying to make a Spring Boot Application with simple login page but when i try to use #Autowired with a interface that i created seems to be a problem. I read 7-8 similar questions but the answers that i find there was useless for me. #Autowired works fine when i use it on interface that expends JpaRepository.
my structure is:
My packages are on the same level as my Application file .
Here is my controller
#Controller
#RequestMapping(value = "/users")
public class LoginContoller {
#Autowired
UsersRepositoryCustom usersRepositoryCustom;
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginForm(){
return "login";
}
#RequestMapping(value = "/login", method = RequestMethod.POST)
public #ResponseBody
String verifyLogin(#RequestParam String name, #RequestParam String password) {
System.out.println("Controller: name: " + name + " pass " + password);
Users users=usersRepositoryCustom.loginUser(name, password);
if (users==null) {
System.out.println("login control user null");
return "login";
}
return "users/all";
}
}
Repository:
#Repository
public interface UsersRepositoryCustom {
Users loginUser(String name, String password);
}
I do not think it helps but here is the implementation
public abstract class UserImpl implements UsersRepositoryCustom {
#Autowired
UsersRepository usersRepository;
#Override
public Users loginUser(String name, String password) {
System.out.println("UserImpl: nume: " + name + " pass " + password);
Users user=usersRepository.findByUsername(name);
if (user != null && user.getPassword().equals(password)) {
System.out.println("User Login"+user.getId()+" "+user.getUsername());
return user;
}
return null;
}
}
Application.properties:
server.port=8080
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url= jdbc:mysql://localhost:3308/assignment-one-db
spring.datasource.username=root
spring.datasource.password=789456123
spring.jpa.hibernate.ddl-auto= update
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.asg1</groupId>
<artifactId>asg1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>asg1</name>
<description>assignment1</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>10</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I try to use #EnableJpaRepositories, #EnableAutoConfiguration but it was useless
Here is the error:
Description:
Field usersRepositoryCustom in com.asg1.asg1.controllers.LoginContoller required a bean of type 'com.asg1.asg1.repository.UsersRepositoryCustom' 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.asg1.asg1.repository.UsersRepositoryCustom' in your configuration.
Process finished with exit code 1

Categories