What's the recommended location for SQL (DDL) scripts?
I think there is no best practice for this. In my past project, I created a separate directory for storing such SQL script.
For example src/main/db
.
It won't be packaged to final JAR by default (which are the preferred way in most case), yet it is convenient enough to let it packaged in assembly. You can even package them in the main artifact JAR, by adding corresponding resource declaration or using maven build-helper plugin.
However, all depends on your usage on this script. My simple "rule of thumb" is that, I would consider putting them in resources/
only when they are really resources to be loaded by the application.
I think it depends entirely on when and how these scripts are processed:
- Compile Time: these are things that your compiler/toolchain consume and produce artifacts. The maven guidance on this very clear, and thus the files would belong somewhere in
src/main/
, likesrc/main/sql
orsrc/main/db
. While I wouldn't do this, I could see these being used by a task at compile to modify your DB. I could see liquibase scripts being used here and then executed via a maven task. - Runtime: these are used by your runtime environment and either modify it, or are consumed by it to produce results. Placing them in
src/main/resources
seems reasonable so that your runtime processes can consume them change your DB as you see fit - say as part of your hot-fix processing on deployment, or as part of your normal DB on-the-fly versioning efforts. Again, maybe you ship liquibase with your app, and then do in-place DB changes that way... - Design Time: This seems to me to be the most likely scenario. Where should I store my DDL in order to properly track them in VCS, and still maintain my maven-compliant structure? For me, this is
src/scripts/sql
orsrc/scripts/db
. This places them as "source" files within the purview of maven, but in a place that is designed to used in a more ad-hoc manner.
src/main/resources
is a good place, but remember it gets packed into your final jar, so it depends if you want to reveal this in your production code or not.
If not, you can filter out this by adding maven-jar-plugin configuration excerpt to appropriate pom.xml
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>src/main/resources/privateSubdir/**</excludes>
</configuration>
</plugin>