Skip to content

Cannot resolve reference to bean 'jpaSharedEM_entityManager' while setting bean property 'entityManager' #3190

@KhanamDEV

Description

@KhanamDEV

Hi team,
I have some issue when using AbstractRoutingDataSource for custom datasource:
This is my error: Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jwtAuthenticationFilter' defined in file [JwtAuthenticationFilter.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'authenticationService' defined in file [AuthenticationService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'userRepositoryInterface' defined in com.tkg.MasterSystem.repositories.UserRepositoryInterface defined in @EnableJpaRepositories declared on DatasourceRoutingConfiguration: Cannot resolve reference to bean 'jpaSharedEM_entityManager' while setting bean property 'entityManager'

This is my config:

@Service
@RequiredArgsConstructor
public class AuthenticationService implements AuthenticationServiceInterface {

    @Autowired
    Environment environment;

    @Value("${JWT_SECRET_KEY}")
    private String jwtSecret;

    private final UserRepositoryInterface userRepository;
public class ClientDataSourceRouter extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return ClientDatabaseContextHolder.getClientDatabase();
    }

    public void initDataSource(DataSource companyA, DataSource companyB){
        Map<Object, Object> datasourceMap = new HashMap<>();
        datasourceMap.put(ClientDatabase.COMPANY_A, companyA);
        datasourceMap.put(ClientDatabase.COMPANY_B, companyB);
        this.setTargetDataSources(datasourceMap);
        this.setDefaultTargetDataSource(companyA);
    }
}

public class ClientDatabaseContextHolder {
    private static ThreadLocal<ClientDatabase> threadLocal = new ThreadLocal<>();

    public static void set(ClientDatabase clientDatabase){
        threadLocal.set(clientDatabase);
    }

    public static ClientDatabase getClientDatabase(){
        return threadLocal.get();
    }

    public static void clear(){
        threadLocal.remove();
    }
}
@Component
public class DataSourceInterceptor extends WebRequestHandlerInterceptorAdapter{

    public DataSourceInterceptor(WebRequestInterceptor requestInterceptor) {
        super(requestInterceptor);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String company = request.getHeader("company");
        if (ClientDatabase.COMPANY_A.toString().equals(company)){
            ClientDatabaseContextHolder.set(ClientDatabase.COMPANY_A);
        } else if(ClientDatabase.COMPANY_B.toString().equals(company)){
            ClientDatabaseContextHolder.set(ClientDatabase.COMPANY_B);
        } else {
            ClientDatabaseContextHolder.set(ClientDatabase.COMPANY_A);
        }
        return super.preHandle(request, response, handler);
    }
}
Configuration
@EnableJpaRepositories(basePackages = "com.tkg.MasterSystem.repositories", transactionManagerRef = "transcationManager", entityManagerFactoryRef = "entityManager")
@EnableTransactionManagement
public class DatasourceRoutingConfiguration {
    @Bean
    @Primary
    @Autowired
    public DataSource dataSource() {
        ClientDataSourceRouter clientDataSourceRouter = new ClientDataSourceRouter();
        clientDataSourceRouter.initDataSource(companyADatasource(), companyBDatasource());
        return clientDataSourceRouter;
    }

    @Bean
    @ConfigurationProperties(prefix = "twt.datasource")
    public DataSource companyADatasource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "tkg.datasource")
    public DataSource companyBDatasource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "entityManager")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(dataSource()).packages(User.class).build();
    }

    @Bean(name = "transcationManager")
    public JpaTransactionManager transactionManager(
            @Autowired @Qualifier("entityManager") LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
        return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactoryBean.getObject()));
    }
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    DataSourceInterceptor dataSourceInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(dataSourceInterceptor).addPathPatterns("/**");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

@Entity(name = "users")
@Table(name = "users")
@Data
public class User implements UserDetails {

    public User() {}

    public User(String title, String firstName, String lastName, String middleName, String email, String password, LocalDate dob,  String avatarUrl,  Boolean status, String countryCode, String phoneNumber, String authenticationCode, LocalDateTime sendAuthenticationCodeAt, Long createdBy) {
        this.title = title;
        this.firstName = firstName;
        this.lastName = lastName;
        this.middleName = middleName;
        this.email = email;
        this.password = password;
        this.dob = dob;
        this.avatarUrl = avatarUrl;
        this.status = status;
        this.countryCode = countryCode;
        this.phoneNumber = phoneNumber;
        this.authenticationCode = authenticationCode;
        this.sendAuthenticationCodeAt = sendAuthenticationCodeAt;
        this.createdBy = createdBy;
    }

    public User(StoreUserRequest request){
        this.title = request.getTitle();
        this.firstName = request.getFirstName();
        this.lastName = request.getLastName();
        this.middleName = request.getMiddleName();
        this.dob = request.getDob();
        this.position = request.getPosition();
        this.department = request.getDepartment();
        this.email = request.getEmail();
        this.countryCode = request.getCountryCode();
        this.phoneNumber = request.getPhoneNumber();
        this.avatarUrl = request.getAvatarUrl();
        this.createdAt = LocalDateTime.now();
        this.updatedAt = LocalDateTime.now();
        this.createdBy = Helper.getAuthUser().getId();
    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    private String title;

    private String firstName;

    private String lastName;

    private String middleName;

    private String email;

    private String password;

    private LocalDate dob;

    private String position;

    private String department;

    private String avatarUrl;

    private Boolean status;

    private String countryCode;

    private String phoneNumber;

    private String authenticationCode;

    private LocalDateTime sendAuthenticationCodeAt;

    private int numberLoginFailed;

    private String forgotPasswordToken;

    private Long createdBy;

    private LocalDateTime createdAt = LocalDateTime.now();

    private LocalDateTime updatedAt;

    private Long deletedBy;

    private LocalDateTime deletedAt;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return email;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return status;
    }

    @Getter(AccessLevel.NONE)
    @OneToMany(mappedBy = "userCreate")
    private List<Permission> permissions;

    @Getter(AccessLevel.NONE)
    @OneToMany(mappedBy = "userCreate")
    private List<Role> roles;

}
@Repository
public interface UserRepositoryInterface extends JpaRepository<User, Long> {
    boolean existsByEmail(String email);

    Optional<User> findByEmail(String email);

    Optional<User> findByForgotPasswordToken(String token);
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions