41

Going by the Spring Boot reference manual, there are a couple of ways in which we can import data on startup of an application. Combined with an in-memory database, this is rather handy for testing.

The options are to create a file called import.sql, which will be picked up by Hibernate, or to create a file called data.sql, which will be picked up by Spring JDBC. Both of these work fine for me.

However, I like to break up my projects a bit, so I currently have a core domain model, where there are some handy imports to configure core data such as some users, which is used everywhere. I also have function-specific projects where it is useful to re-use that same import of base data, but also import some additional data which is specific to that function.

This is where things are not working so well.

I found an answer to a previous question, where Pascal Thivent mentioned that the hibernate.hbm2ddl.import_files property could be used to define a list of files, as of Hibernate 3.6.0.Beta1. Given that my project is importing 4.3.1.Final, I thought that perhaps this would be available.

So I tried adding the following to my Spring Boot application.properties:

spring.jpa.hibernate.hbm2ddl.import_files=/another-import.sql

and:

hibernate.hbm2ddl.import_files=/another-import.sql

Unfortunately, neither of these would cause the import to run.

So I'm wondering whether I just made a mess of the properties above (quite likely). Or is there something else that I need to do?

Note that as a workaround, I spotted that Spring JDBC seems to run data.sql after Hibernate runs import.sql. So as long as I don't need more than two imports, I'm able to use import.sql for the base data and then put project-specific imports in data.sql. I can get by with this, but it's not really a solution.

Community
  • 1
  • 1
Steve
  • 9,270
  • 5
  • 47
  • 61
  • are you defining your own jpaProperties and entityManagerFactory beans, or using the default magic? – guido Jul 01 '14 at 10:45
  • It's all just default magic. :) – Steve Jul 01 '14 at 11:14
  • 1
    use `spring.jpa.properties.hibernate.hbm2ddl.import_files`. See [reference guide](http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html) for a list of properties. If you want multiple resources just use a common separated list for `spring.datasource.data` and/or `spring.datasource.schema` (which default to `data` and `schema` respectively. Or you can come up with a naming convention and put the expression in there `spring.datasource.data=classpath:/META-INF/sql/init-*.sql` for instance. – M. Deinum Jul 01 '14 at 12:00

1 Answers1

54

If you really want to use the hibernate property prefix it with spring.jpa.properties. as those are added as is as properties to the EntityManagerFactory. See here in the Spring Boot reference guide.

spring.jpa.properties.hibernate.hbm2ddl.import_files=file1.sql,file2.sql

However you can also use the spring.datasource.data and spring.datasource.schema properties to your advantage. They default to respectively data and schema. As you can see in the DataSourceInitializer class. You can also set them and they take a comma separated list of resources.

spring.datasource.data=classpath:/data-domain.sql,file:/c:/sql/data-reference.sql,data-complex.sql

It gets even better because the resource loading also allows loading resources with ant-style patterns.

spring.datasource.data=/META-INF/sql/init-*.sql
spring.datasource.schema=/META-INF/sql/schema-*.sql 
김준호
  • 15,997
  • 9
  • 44
  • 38
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • That's the one ... a typo in my properties file. I think I made the same mistake before, because there are some `spring.jpa.hibernate` properties in my configs, so I just followed the same pattern. – Steve Jul 01 '14 at 12:16
  • 1
    I had to prefix the lines with "classpath*:/META-INF/..." (classpath with asterisk), to read files from other Maven modules. Nice answer, thanks! – Stefan Jun 02 '16 at 07:42
  • 3
    Ditto w/ the `classpath*:` being needed even just for local packaged files. I wanted to separate my stuff out more and use Flyways like conventions, so I have `spring.datasource.data=classpath*:db/data/V*.sql` – Snekse May 23 '17 at 16:07