8

I'm using PostgreSQL and spring-boot-2.0.1 and want my app to create the database if it doesn't exist. I have the below options in my application.properties

spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL94Dialect

spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=123

with the above i'm getting error:

Caused by: org.postgresql.util.PSQLException: FATAL: database "mydb" does not exist

any idea what i'm missing?

Ahmed Lotfy
  • 1,065
  • 2
  • 15
  • 33

5 Answers5

4

Since all Postgres installations come with a default database, technically it should be possible to connect to it at the very beginning (when the application starts) and then to call

CREATE DATABASE

This is something you could do programmatically before spring initializes, but after the properties are read, for example in Environment Post Processor

The so-early invocation is required because you probably want to take advantage of the properties read by spring boot on one hand, but by the time the spring boot beans will start to get the newly created database in the "operational" state.

So, technically its possible. However, I can't see a real use-case for this scenario. If it's for tests, then you can perfectly use the default Postgres database, that was mentioned in the very beginning of the question.

If it's for production environment - usually DBAs won't allow that, because in order to be able to run that CREATE DATABASE statement, the user that connects to Postgres (spring boot application in this case) should have a very "strong" createdb priviledge, something that DBA won't really want to share.

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
4

Spring Boot

Postgres does not support createDatabaseIfNotExist=true So you can try a similar way and it worked for me see Screenshot

@SpringBootApplication
public class SpringSecurityJwtApplication{

    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(SpringSecurityJwtApplication.class);
        Connection connection = null;
        Statement statement = null;
        try {
            logger.debug("Creating database if not exist...");
            connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/", "postgres", "postgres");
            statement = connection.createStatement();
            statement.executeQuery("SELECT count(*) FROM pg_database WHERE datname = 'database_name'");
            ResultSet resultSet = statement.getResultSet();
            resultSet.next();
            int count = resultSet.getInt(1);

            if (count <= 0) {
                statement.executeUpdate("CREATE DATABASE database_name");
                logger.debug("Database created.");
            } else {
                logger.debug("Database already exist.");
            }
        } catch (SQLException e) {
            logger.error(e.toString());
        } finally {
            try {
                if (statement != null) {
                    statement.close();
                    logger.debug("Closed Statement.");
                }
                if (connection != null) {
                    logger.debug("Closed Connection.");
                    connection.close();
                }
            } catch (SQLException e) {
                logger.error(e.toString());
            }
        }
        SpringApplication.run(SpringSecurityJwtApplication.class, args);
    }
}
3

You can create a database if it doesn't exist with spring boot. At least with MySQL, we do:

spring.datasource.url=jdbc:mysql://localhost:3306/mydb?createDatabaseIfNotExist=true

So it should be the same with PostgreSQL:

spring.datasource.url= jdbc:postgresql://localhost:5432/mydb?createDatabaseIfNotExist=true

This doesn't work with PostgreSQL.

Tobias S.
  • 21,159
  • 4
  • 27
  • 45
ISlimani
  • 1,643
  • 14
  • 16
0

Short answer:

It cannot be done like the way we do in MySQL you need to find a way to do it yourself out of Spring Configuration

Ahmed Lotfy
  • 1,065
  • 2
  • 15
  • 33
0

A solution would be to add the script for database creation ... even though, you don't have "if not exist" in postgres. Here is how i solved the issue with a docker file, but you can do a sql script in postgres i guess. I put this inside initdb.sh ...

set -e
export PGPASSWORD=$POSTGRES_PASSWORD;
psql -v ON_ERROR_STOP=1 --username "root" --dbname "mydb" <<-EOSQL
  SELECT 'CREATE DATABASE mydb' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'mydb')\gexec
  GRANT ALL PRIVILEGES ON DATABASE mydb TO root;
  \connect mydb root
EOSQL
davidvera
  • 1,292
  • 2
  • 24
  • 55