1

I tried to create and initialize automatically a database into MySQL called "spring" to store users and authorities, so I created the files schema.sql and data.sql in the "resources" folder (see the scripts below). When I run the program, it throws an Exception declaring that "datasource" bean could not be instantiated as the "spring" database, which I tried to create, is not found !!

PS: The program works fine, when I switch into the in-memory database H2, but when I switch to MySQL the problem fails as described above.

It seems to me that spring boot is trying to create the "dataSource" bean before executing the SQL scripts for the database for the case of MySQL.

Could anyone explain to me what's really happening ?

Here's program involving the datasource bean :

package com.javamaster.springsecurityjdbc.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;

import javax.sql.DataSource;

@Configuration
public class SecurityConfig {

    @Bean
    public UserDetailsService userDetailsService(DataSource dataSource){
        return new JdbcUserDetailsManager(dataSource);
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }
}

schema.sql

create database spring;

CREATE TABLE IF NOT EXISTS `spring`.`users` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(45) NOT NULL,
    `password` VARCHAR(45) NOT NULL,
    `enabled` INT NOT NULL,
    PRIMARY KEY (`id`));

CREATE TABLE IF NOT EXISTS `spring`.`authorities` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(45) NOT NULL,
    `authority` VARCHAR(45) NOT NULL,
    PRIMARY KEY (`id`));

data.sql

INSERT IGNORE INTO `spring`.`authorities` VALUES (NULL, 'tom', 'write');
INSERT IGNORE INTO `spring`.`users` VALUES (NULL, 'tom', '123456', '1');

and application.properties

spring.datasource.url=jdbc:mysql://localhost/spring?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.initialization-mode=always

2
  • spring.jpa.generate-ddl=true ? Commented Jan 17, 2021 at 0:01
  • actually I'm not using JPA, just JDBC Commented Jan 17, 2021 at 0:40

1 Answer 1

0

You most likely getting either:

Failed to obtain JDBC Connection; nested exception is java.sql.SQLSyntaxErrorException: Unknown database 'spring'

or

Failed to execute SQL script statement #1 of URL: create database spring; nested exception is java.sql.SQLException: Can't create database 'spring'; database exists

You need to create database manually, outside of the script:

schema.sql

-- create database spring; <-- remove this line

CREATE TABLE IF NOT EXISTS `spring`.`users` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(45) NOT NULL,
    `password` VARCHAR(45) NOT NULL,
    `enabled` INT NOT NULL,
    PRIMARY KEY (`id`));

CREATE TABLE IF NOT EXISTS `spring`.`authorities` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(45) NOT NULL,
    `authority` VARCHAR(45) NOT NULL,
    PRIMARY KEY (`id`));

As per above exceptions, in the first case Spring tries to connect to database before running any scripts on it, therefore can't find it and fails. In second scenario, it was able to connect, but the database was already created, therefore script fails.

I tested these locally and was able to successfully run the application, once removed create database part. Both tables were created and populated correctly.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @skryvets, it works fine, actually I've got the first exception

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.