Reputation: 226
Hi my simple Spring Boot Security project
My UserController
@RestController
@RequestMapping(path= "/api")
@RequiredArgcContructor
public class UserController {
private final UserService userService;
@PostMapping
public String create(@RequestBody UserDTO userDto){
return userService.save(userDto);
}
}
My UserService
@Service
@RequiredArgsConstructor
public class UserService {
private UserManager userManager;
private Mapper<UserDTO, UserEntity> userDTOUserMapper;
public String save(UserDTO userDto) {
return userManager.signUp(userDTOUserMapper.map(userDto));
}
}
My UserManager
package com.userlogintask.userlogintask.business;
import com.userlogintask.userlogintask.model.TokenEntity;
import com.userlogintask.userlogintask.model.UserEntity;
import com.userlogintask.userlogintask.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.UUID;
@Component
@RequiredArgsConstructor
public class UserManager implements UserDetailsService {
private final static String USER_NOT_FOUND_msg="user with email %s not found";
private final UserRepository userRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final TokenManager tokenManager;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return userRepository.findByEmail(email)
.orElseThrow(()-> new UsernameNotFoundException(String.format(USER_NOT_FOUND_msg,email)));
}
public String signUp(UserEntity userEntity){
boolean isExist = userRepository.findByEmail(userEntity.getEmail()).isPresent();
if(isExist){
throw new IllegalStateException("email is already exists");
}
String encodePassword = bCryptPasswordEncoder.encode(userEntity.getPassword());
userEntity.setPassword(encodePassword);
userRepository.save(userEntity);
//TODO:Send confirmation token;
String token = UUID.randomUUID().toString();
TokenEntity confirmationTokenEntity = new TokenEntity(
token,
LocalDateTime.now(),
LocalDateTime.now().plusMinutes(15),
userEntity
);
tokenManager.saveConfirmationToken(confirmationTokenEntity);
//TODO:Send email
return token;
}
public int enableAppUser(String email) {
return userRepository.enableUser(email);
}
}
My Mapping Configuration
@Configuration
public class ApiMappingConfig {
//userDTO mapping user
@Bean
public Mapper<UserDTO, UserEntity> userDTOUserMapper(){
return Mapping.from(UserDTO.class)
.to(UserEntity.class)
.omitInDestination(UserEntity::getLocked)
.omitInDestination(UserEntity::getUser_id)
.omitInDestination(UserEntity::getEnabled)
.mapper();
}
}
My UserEntity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class UserEntity implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id",unique = true)
private Long user_id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
private String email;
private String password;
@Enumerated(EnumType.STRING)
private UserRole userRole;
private Boolean locked = false;
private Boolean enabled = false;
public UserEntity(String firstName,
String lastName, String email,
String password, UserRole userRole) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
this.userRole = userRole;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singleton(new SimpleGrantedAuthority(userRole.name()));
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return email;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return !locked;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return enabled;
}
}
My UserDTO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
private String firstName;
private String lastName;
private String email;
private String password;
private UserRole userRole;
}
My Main Class
@SpringBootApplication
public class UserlogintaskApplication {
public static void main(String[] args) {
SpringApplication.run(UserlogintaskApplication.class, args);
}
}
My Error
Error creating bean with name 'userController' defined in file [C:\Users\user\Desktop\Java\userlogintask\target\classes\com\userlogintask\userlogintask\controller\UserController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService' defined in file [C:\Users\user\Desktop\Java\userlogintask\target\classes\com\userlogintask\userlogintask\service\UserService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDTOUserMapper' defined in class path resource [com/userlogintask/userlogintask/mapping/ApiMappingConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.remondis.remap.Mapper]: Factory method 'userDTOUserMapper' threw exception; nested exception is com.remondis.remap.MappingException: The get-method for property 'enabled' in type com.userlogintask.userlogintask.model.UserEntity is not a valid Java Bean property. at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.5.jar:5.3.5] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.5.jar:5.3.5] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.4.jar:2.4.4] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:769) ~[spring-boot-2.4.4.jar:2.4.4] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) ~[spring-boot-2.4.4.jar:2.4.4] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~[spring-boot-2.4.4.jar:2.4.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~[spring-boot-2.4.4.jar:2.4.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1313) ~[spring-boot-2.4.4.jar:2.4.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-2.4.4.jar:2.4.4] at com.userlogintask.userlogintask.UserlogintaskApplication.main(UserlogintaskApplication.java:14) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.4.4.jar:2.4.4] Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService' defined in file [C:\Users\user\Desktop\Java\userlogintask\target\classes\com\userlogintask\userlogintask\service\UserService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDTOUserMapper' defined in class path resource [com/userlogintask/userlogintask/mapping/ApiMappingConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.remondis.remap.Mapper]: Factory method 'userDTOUserMapper' threw exception; nested exception is com.remondis.remap.MappingException: The get-method for property 'enabled' in type com.userlogintask.userlogintask.model.UserEntity is not a valid Java Bean property. at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.5.jar:5.3.5] ... 25 common frames omitted Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDTOUserMapper' defined in class path resource [com/userlogintask/userlogintask/mapping/ApiMappingConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.remondis.remap.Mapper]: Factory method 'userDTOUserMapper' threw exception; nested exception is com.remondis.remap.MappingException: The get-method for property 'enabled' in type com.userlogintask.userlogintask.model.UserEntity is not a valid Java Bean property. at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.5.jar:5.3.5] ... 39 common frames omitted Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.remondis.remap.Mapper]: Factory method 'userDTOUserMapper' threw exception; nested exception is com.remondis.remap.MappingException: The get-method for property 'enabled' in type com.userlogintask.userlogintask.model.UserEntity is not a valid Java Bean property. at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.5.jar:5.3.5] at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.5.jar:5.3.5] ... 53 common frames omitted Caused by: com.remondis.remap.MappingException: The get-method for property 'enabled' in type com.userlogintask.userlogintask.model.UserEntity is not a valid Java Bean property. at com.remondis.remap.MappingException.notAProperty(MappingException.java:55) ~[remap-4.2.5.jar:4.2.5] at com.remondis.remap.MappingConfiguration.getPropertyDescriptorOrFail(MappingConfiguration.java:574) ~[remap-4.2.5.jar:4.2.5] at com.remondis.remap.MappingConfiguration.getPropertyFromFieldSelector(MappingConfiguration.java:550) ~[remap-4.2.5.jar:4.2.5] at com.remondis.remap.MappingConfiguration.omitInDestination(MappingConfiguration.java:117) ~[remap-4.2.5.jar:4.2.5] at com.userlogintask.userlogintask.mapping.ApiMappingConfig.userDTOUserMapper(ApiMappingConfig.java:23) ~[classes/:na] at com.userlogintask.userlogintask.mapping.ApiMappingConfig$$EnhancerBySpringCGLIB$$952967e9.CGLIB$userDTOUserMapper$0() ~[classes/:na] at com.userlogintask.userlogintask.mapping.ApiMappingConfig$$EnhancerBySpringCGLIB$$952967e9$$FastClassBySpringCGLIB$$7199a018.invoke() ~[classes/:na] at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.5.jar:5.3.5] at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.5.jar:5.3.5] at com.userlogintask.userlogintask.mapping.ApiMappingConfig$$EnhancerBySpringCGLIB$$952967e9.userDTOUserMapper() ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.5.jar:5.3.5] ... 54 common frames omitted Process finished with exit code 0
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.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.userlogintask</groupId>
<artifactId>userlogintask</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>userlogintask</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>15</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-security</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.20</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.remondis</groupId>
<artifactId>remap</artifactId>
<version>4.2.5</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<optional>true</optional>
</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>
<version>2.4.4</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
What is the problem ? I am dont understand
Upvotes: 0
Views: 573
Reputation: 42461
Ok, it looks like the error is:
.MappingException: The get-method for property 'enabled' in type com.userlogintask.userlogintask.model.UserEntity is not a valid Java Bean property. at
That's why the mapper can't be created as it needs to, and this in turn causes the BeanInitializationException
of the service.
Looking at your entity, you use:
Boolean
for enabled
property, but the getter returns boolean
(not a wrapper class but a real primitive). Try to change that and see what happens.
Now I haven't worked with Mappers so I can't really comment on the semantics of omitInDestination
method that you call while creating the mapper. However I think you can place a breakpoint and make sure that spring initializes the mapper out of your configuration, kind of generic "common sense" advice.
Upvotes: 0