47

While I was using Spring Boot 1.5, on application startup Hibernate executed schema.sql file located in /resources folder when appropriate configuration is set. After Spring Boot 2.0 release this feature does not work any more. I couldn't find anything about this change in documentation. Here is my application.properties file content:

spring.datasource.url=...
spring.datasource.username=...
spring.datasource.password=...

spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

Is there some change in Spring Boot 2.0 or is this an bug/issue?

Saikat
  • 14,222
  • 20
  • 104
  • 125
Đorđe Pržulj
  • 491
  • 1
  • 4
  • 9

7 Answers7

58

Check the documents here.

In a JPA-based app, you can choose to let Hibernate create the schema or use schema.sql, but you cannot do both. Make sure to disable spring.jpa.hibernate.ddl-auto if you use schema.sql.

You have spring.jpa.hibernate.ddl-auto=create-drop that's why schema.sql is not executed. Looks like this is the way Spring Boot works.

Edit

I think that the problem(not really a problem) is that your application points to a mysql instance.

See the current Spring Boot properties:

spring.datasource.initialization-mode=embedded # Initialize the datasource with available DDL and DML scripts.

The default value is embedded - e.g. initialize only if you're running and embedded database, like H2.

Also see the answer of Stephan here. He said:

Adding spring.datasource.initialization-mode=always to your project is enough.

So try to set:

spring.datasource.initialization-mode=always
Evgeni Dimitrov
  • 21,976
  • 33
  • 120
  • 145
  • 1
    Sorry, my fault. Even with `spring.jpa.hibernate.ddl-auto=none` this doesn't work. I just edited original post. – Đorđe Pržulj Mar 22 '18 at 21:34
  • 5
    It works before Spring 2.0, I don't know why it's not anymore but I'm also looking for an answer. I just need to create a schema for `h2` in `schema.sql`, since I have upgraded to 2.0 it stopped working. – 11thdimension Mar 27 '18 at 00:12
  • 2
    @11thdimension Looks like new major Spring Boot release doesn't support it. It would be nice we can find this in documentation. – Đorđe Pržulj Mar 28 '18 at 09:32
  • I already tried it, it still didn't work. However it got resolved after I excluded HikariCP dependency added to to Spring Boot 2. – 11thdimension Mar 29 '18 at 14:44
  • @EvgeniDimitrov The answer is correct but in my case it goes into some dependency cyclic loop , as show [here](https://github.com/spring-cloud/spring-cloud-security/issues/143) – charle819 Aug 13 '18 at 09:14
  • It worked for me with spring.sql.init.mode=always. why is it different? – AMZ Jan 23 '23 at 10:31
33

Not embedded (e.g. MySQL)

If you load a database that is not embedded, in Spring Boot 2 you need to add:

spring.datasource.initialization-mode=always

Check the Migration Guide:

Database Initialization

Basic DataSource initialization is now only enabled for embedded data sources and will switch off as soon as you’re using a production database. The new spring.datasource.initialization-mode (replacing spring.datasource.initialize) offers more control.


Embedded (e.g. h2)

I once had a similar problem, even though it was an h2 (so it was an embedded DB), my h2 configuration was activated by a my-test profile.

My test class was like:

@RunWith(SpringRunner.class)
@SpringBootTest                     // does not work alone
@ActiveProfiles("my-test")
public class MyEntityRepositoryTest {

The problem is @SpringBootTest alone did not initialize the test database. I had to either use @DataJpaTest or @SpringBootTest+@AutoConfigureTestDatabase. Examples

@RunWith(SpringRunner.class)
@DataJpaTest                       // works
@ActiveProfiles("sep-test")
public class MyEntityRepositoryTest {

or

@RunWith(SpringRunner.class)
@SpringBootTest                     // these two
@AutoConfigureTestDatabase          // together work
@ActiveProfiles("sep-test")
public class MyEntityRepositoryTest {
acdcjunior
  • 132,397
  • 37
  • 331
  • 304
  • This suggestion has been deprecated and you now in later versions use ´spring.sql.init.mode=always´. See post from @Panagiotis Bougioukos. – MiB May 03 '23 at 19:25
15

Recent Update

As of Spring Boot Version 2.7

the property spring.datasource.initialization-mode has been removed.

You should from this version and onwards use the replacement property spring.sql.init.mode

Example: spring.sql.init.mode:always

Spring Boot 2.7 changelog

Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47
4

It works fine for me, you can try it. Set datasource type to what you like instead of HikariCP.

spring.datasource.initialization-mode=always
spring.datasource.type=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
spring.jpa.hibernate.ddl-auto=none
Jack Zhou
  • 163
  • 7
3

There might be another problem causing data.sql not to be executed, If you don't config the spring.jpa.hibernate.ddl-auto=none, the data.sql will not be executed.

user3399000
  • 353
  • 3
  • 18
jay chang
  • 101
  • 1
  • 1
1

I was able to make application run only after excluding Hikary CP like that:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Please, see the issue here

Wytrzymały Wiktor
  • 11,492
  • 5
  • 29
  • 37
stinger
  • 3,790
  • 1
  • 19
  • 30
0

For me, for some reason, Spring didn't find the schema.sql file in the classpath. I had to specify it explicitly for it to work:

spring.sql.init.schema-locations=classpath:/sql/schema.sql
shemerk
  • 257
  • 5
  • 16