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=create-drop
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?
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
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 {
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
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
There have another problem may result data.sql can not be executed,when you don't config the spring.jpa.hibernate.ddl-auto=none,that the data.sql will not be execute d.
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
Related
I'm trying use to postgresql but i have this error.Here's my application properties
server.port=8081
application.name= = Address Registration
application.version = 1.0.0
spring.datasource.url= jdbc:postgresql://localhost:5432/addressRegistration
spring.datasource.username= postgres
spring.datasource.password= 12345
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update
This can happen during the context loading when spring registers the beans required to finalize the program execution. There can be few options to check.
The dependency for h2 database is missing in your pom.xml. Hence the jar was not downloaded in the classpath.
Autoconfiguration is messed up. You can try with #EnableAutoConfiguration( exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
You might have some settings left with h2 database in your app.properties, however you don't want to use h2 database.
I am using Spring Boot 2.2.2 with Flyway 5.2.4 and I tried to configure flyway to use a differente location for the scripts, but spring.flyway.locations=filesystem:db_other/migration/{vendor} neither flyway.locations=filesystem:db_other/migration/{vendor} configurations on application.properties worked.
When running the program, the following exception appear in the log:
FlywayMigrationScriptMissingException: Cannot find migration scripts in: [classpath:db/migration]
I already tried using Spring Boot 2.2.1, 2.2.0, 2.1.11 and Flyway 6.1.0 and 6.1.3, but the result is the same.
The default value for that property is classpath:db/migration as shown here (search for flyway).
Since you're using a different folder in the resources directory you should only need to change "filesystem" to "classpath" in your application.properties value.
Actually if was my fault: as I used to work with just spring (not spring boot) I configured my test class with the annotations #ExtendWith(SpringExtension.class) AND #ContextConfiguration(classes = { MyConfiguration.class }) instead of just use #SpringBootTest. When making this change the test worked.
I've got a Java Spring Boot application, with Flyway configured as a dependency in my Maven pom.xml (I have a parent pom and a project pom... Flyway is defined in my project pom).
<dependencies>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>4.2.0</version>
</dependency>
...
and just a couple of entries in application.properties:
flyway.enabled=true
flyway.out-of-order=true
I can run a maven task to get Flyway to run migrate to create/update my database and then run my application against that, but I'm having trouble getting it to call migrate at the right time just by running my application (which is obviously important in prod). It looks like all of my Spring classes are being instantiated first, some of which involves looking at the database, and then Flyway migration happens after, so for instance if you run the application against an empty database the application crashes when trying to access anything in the database.
Any tips on where to look to see where I'm going wrong to get Flyway to do its migration earlier in the start-up process of my Spring Boot application?
I am not sure how your data source configuration looks like, but you could declare your JPA config in such a way that makes it dependent on the flyway migration.
You could declare a #DependsOn("flyway") annotation on whatever #Config class or datasource bean, "flyway" being the declared name of your flyway configuration bean. Then, on your flyway configuration bean, qualify the bean annotation with an initMethod property like the following: #Bean(initMethod = "migrate").
Try change "flyway.out-of-order=false"
I would suggest you to try using event listners like ApplicationStartedEvent.
#EventListener
public void migrate(ApplicationStartedEvent applicationStartedEvent) {
//do some checks
flyway.migrate();
}
Background: i am hosting the trial version of jooq 3.9.1 (proprietary eg oracle db compatible) in my nexus repository - all the dependencies in my pom relating to jooq point to that.
i have this line in my application.properties
jooq.sql-dialect=ORACLE
but when i inspect the injected dslContext the dialect is set to "DEFAULT" and not ORACLE as expected/desired.
I am currently getting round it by autowiring the datasource rather than the dslcontext and then setting the sql dialect (as shown below) - but wondering why autowiring the dslcontext directly doesnt work as expected
#Autowired
private DataSourceConnectionProvider dataSource;
public static final SQLDialect sqlDialect = SQLDialect.ORACLE;
public DSLContext getDSL(){
return DSL.using(dataSource, sqlDialect);
}
Lukas' comment Spring Boot JOOQ sql dialect not picked up from application.properties is correct.
Here is an example how to do it and test:
Inside application.properties
spring.jooq.sql-dialect = Postgres
And tested with an integration test ConfigIT:
#RunWith(SpringRunner.class)
#JdbcTest
#ImportAutoConfiguration(JooqAutoConfiguration.class)
public class ConfigIT {
#Autowired
private DSLContext dSLContext;
#Test
public void dialectShouldBePickedUp() {
assertThat(dSLContext.configuration().dialect(), is(SQLDialect.POSTGRES));
}
}
You'll find the working and tested example in the repositories of http://springbootbuch.de here: https://github.com/springbootbuch/database_examples
What's important ist to choose the right, case sensitive name. In my example, it's Postgres, in your example it should be Oracle and you must use the right property. Sadly, those names vary across different tool sets. For jOOQ you'll find the constants in org.jooq.SQLDialect
Spring Boot by default uses the org.jooq dependency, which is the Maven groupId for the jOOQ Open Source Edition:
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq</artifactId>
</dependency>
However, the Oracle SQLDialect is contained only in the commercial distributions of jOOQ, which are available under different groupId (and not from Maven Central but from here (trial) and here (express, professional, enterprise edition)):
<groupId>org.jooq.pro</groupId> <!-- for commercial editions -->
<groupId>org.jooq.pro-java-6</groupId> <!-- for commercial editions with Java 6 support -->
<groupId>org.jooq.trial</groupId> <!-- for the free trial edition -->
The distributions are almost completely binary compatible, so you should be able to simply replace the <groupId> in your own pom.xml for Spring Boot to work with jOOQ and Oracle.
I've discovered that spring boot silently ignores all datasource properties loaded through org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.
My application.yml contains:
spring:
datasource:
name: this is not ignored
url: this is ignored
During startup i see line:
o.s.j.d.e.EmbeddedDatabaseFactory : Creating embedded database 'this is not ignored'
Debugging shows that DataSourceProperties object has not any properties set during call to getUrl (debugging also shows that exception is thrown but it is silently ignored because it is not visible in logs).
Url is obvoiusly invalid but database is somehow initialized.
Tested on 1.2.7 version.
What can cause such strange behaviour? How can I debug it further?
Adding
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
to dependencies solved problem.
Problem was caused by Spring Boot autoconfiguration magic - I was not using correct spring boot starter.