0

This is the definition for the databases in the application.properties file: First Database:

spring.datasource.jdbc-url=jdbc:mysql://localhost:3306/police_db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=Admin
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver

Second database configuration:

enroll.datasource.jdbc-url=jdbc:mysql://localhost:3306/enrollment_db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
enroll.datasource.username=root
enroll.datasource.password=Admin
enroll.datasource.driverClassName=com.mysql.cj.jdbc.Driver

I created two configuration classes for the two databases, this is the configuration class for the first or primary database:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory",
        basePackages = {"com.cpm.repository"})
public class PoliceDbConfig {

    @Primary
    @Bean(name = "dataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder, @Qualifier("dataSource") DataSource dataSource) {
        return builder.dataSource(dataSource).packages("com.cpm.model").persistenceUnit("model")
                .build();
    }


    @Primary
    @Bean(name = "transactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

This is the configuration class for the second database:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "barEntityManagerFactory",
        transactionManagerRef = "barTransactionManager", basePackages = {"com.enrollment.repository"})
public class EnrollmentDbConfig {

    @Bean(name = "enrollmentDatasource")
    @ConfigurationProperties(prefix = "enroll.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "barEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean barEntityManagerFactory(
            EntityManagerFactoryBuilder builder, @Qualifier("enrollmentDatasource") DataSource dataSource) {
        return builder.dataSource(dataSource).
                packages("com.enrollment.model").
                persistenceUnit("model")
                .build();
    }

    @Bean(name = "barTransactionManager")
    public PlatformTransactionManager barTransactionManager(
            @Qualifier("barEntityManagerFactory") EntityManagerFactory barEntityManagerFactory) {
        return new JpaTransactionManager(barEntityManagerFactory);
    }
}

The major problem i am having is the tables for the entities are not automatically generated, i did a web search for the problem and i was told to add this annotations:

spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create

The first annotation creates the tables but if i remove it and leave just the second annotation which is what i need, the tables do not get created.

Another issue is I have an sql script in the resources folder which is supposed to run and populate the tables when the application is started, but it does not do so.

The final issue is, I have basic authentication set up using spring security, but I still get unauthorized when I test any of my endpoints, so I guess that's because the users table is not populated when the application is started, so I then added the users via MYSQL workbench manually and tried the endpoint, but it still results in unauthorized error.

Any help on these issues would be very much appreciated. UPDATE: This is the security configuration class:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final SystemUserDetailService userDetailsService;

    @Autowired
    public SecurityConfig(SystemUserDetailService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                //.antMatchers("/verification/**","/admin/**", "/login/**","/logout/**").authenticated()
                .antMatchers("/verification/**","/admin/**", "/login/**","/logout/**").authenticated()
                .and()
                .httpBasic()
                .realmName("Bio Connect")
                .and()
                .csrf()
                .disable();
    }
}

Also, this is my UserDetailService Class:

@Component
public class SystemUserDetailService implements UserDetailsService {

    private final SystemUserRepository repository;

    @Autowired
    public SystemUserDetailService(SystemUserRepository repository) {
        this.repository = repository;
    }

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        SystemUser user = repository.findByUsername(s);
        if(user == null) {
            throw new UsernameNotFoundException(String.format("User with the username %s doesn't exist", s));
        }

        // Create a granted authority based on user's role.
        // Can't pass null authorities to user. Hence initialize with an empty arraylist
        List<GrantedAuthority> authorities = new ArrayList<>();
        if(user.isAdmin()) {
            authorities = AuthorityUtils.createAuthorityList("ROLE_ADMIN");
        }
        // Create a UserDetails object from the data
        UserDetails userDetails = new User(user.getUsername(), user.getPassword(), authorities);

        return userDetails;
    }
}
caleb grimah
  • 183
  • 1
  • 15
  • Possible duplicate https://stackoverflow.com/questions/43122329/tables-not-getting-created-in-multiple-databases-in-spring-boot-application – IMParasharG Jan 27 '19 at 13:00
  • Could you add your Spring Security Configuration as well? – Pranjal Gore Jan 27 '19 at 13:11
  • 1
    It's not okay to ask multiple big questions in one post, if question and answers contain your both Spring Data JPA and Spring security questions then the posts will be so long so for your security related question create another post – void Jan 27 '19 at 13:22
  • stick to one issue at a time in order to get maximum benefit from stackians! Create issues separately to boost feedback and solutions. – ScanQR Jan 27 '19 at 13:26
  • I have added the class for the Security configuration, – caleb grimah Jan 27 '19 at 13:43
  • @pranjalGore i have added the classes for security configuration – caleb grimah Jan 27 '19 at 13:47
  • I'm voting to close this question as off-topic because of multiple questions in one post which may be oppinion based – void Jan 27 '19 at 13:51
  • @Null, can you give your opinion on an answer before you do that? – caleb grimah Jan 27 '19 at 14:05

1 Answers1

0

Although you havn't shown us all related codes, I guess the problem is your project structure and how you created entities and repositories.

To work with two separate database with spring, I prefer to have two separate packages for entities of your both databases, you also need to have separate Repositories for your both databases

src/main/java
- com.multipledb   //Your db config classes are located here
  - firstdb
    - model  //entities of first database are located here
    - dao    //repositories of first database are located here
  - seconddb
    - model  //entities of second database are located here
    - dao    //repositories of second database are located here
void
  • 7,760
  • 3
  • 25
  • 43
  • I am using the same structure, but in my model folder, there's another nested folder containing models, is that going to be a problem – caleb grimah Jan 27 '19 at 13:44