Archetype
database-audits-spring-boot-integration-archetype scaffolds an audit test suite into a consumer’s project.
Two generation modes are supported, controlled by the generateMode property:
project(default) — generates the abstract base IT class, all catalog/JPA/runtime audit ITs, and a Testcontainers demo harness for the chosendatabasePlatform(PostgreSQL by default). Use this to start fresh with a self-contained, runnable example.tests-only— generates only the audit test classes (no demo app, no entities, no DataSource setup, noRepositoryWorkloadIT). Use this when you already have a Spring Boot application and only want the audit ITs dropped in alongside your existing test infrastructure — your own tests prime the SQL capturer before the runtime audit ITs run.
The archetype also doubles as the project’s end-to-end test: the build generates and validates multiple
samples on every clean install — project samples that run their integration tests against
Testcontainers PostgreSQL and MySQL, and several tests-only samples (covering the default configuration,
the projectDirectory option, and the parentClass option) that compile the generated sources to
verify generation correctness.
Run archetype:generate from any directory. Use -DoutputDirectory to control where the generated
project is written, or omit it to generate in the current directory.
Note: Generation is not idempotent. In project mode the plugin refuses to generate into a directory
that already contains a pom.xml. In tests-only mode the post-generate copy step silently overwrites
any existing file of the same name — see the tests-only section
for the full warning.
Note: Replace VERSION in the commands and dependency snippet below with the latest released
database-audits-spring-boot-integration version.
Generate the full project
mvn archetype:generate -DinteractiveMode=false \
-DarchetypeGroupId=io.github.database-audits \
-DarchetypeArtifactId=database-audits-spring-boot-integration-archetype \
-DarchetypeVersion=VERSION \
-DgenerateMode=project \
-DgroupId=com.example \
-DartifactId=demo \
-Dpackage=com.example.demo \
-DschemaName=public \
-DschemaPropertyName=database.datasource.schema-name \
-DparentClass=com.example.MySpringTestBase \
-DdatabaseAuditsVersion=VERSION \
-DspringBootVersion=4.1.0 \
-DdatabasePlatform=postgresql \
-DdatabaseImage=none \
-DdisabledTests=false \
-DreportFormat=asciidoc \
-DfixFormat=liquibase-xml \
-DfixPlacement=both \
-DdataSourceName=none \
-DoutputDirectory=/path/to/outputGenerate tests only (for an existing project)
Point -DoutputDirectory at a pom-less scratch directory (e.g. target/audit-scratch; use a path valid on your OS — a Unix-style /tmp path is mis-resolved on Windows) — the plugin refuses
to generate into a directory containing a pom.xml, and when run from inside a Maven project it tries to add
the result as a <module>. The scratch location avoids both pitfalls; only the post-generate copy step writes
to your project.
Set -DprojectDirectory to your project root: an absolute path, or a path relative to the directory you
run the command from — use . when you run from the project root itself. The post-generate script
copies the generated src/ tree into projectDirectory and deletes the scratch directory.
Warning: The post-generate copy step silently overwrites any existing file of the same name in
-DprojectDirectory without prompting or backing up. Re-running generation on a project that already
contains generated files will clobber any customizations you have made to them. Commit or back up
your changes before regenerating.
# Run from your project root. -DoutputDirectory is a throwaway scratch dir; -DprojectDirectory=. is your project.
mvn archetype:generate -DinteractiveMode=false \
-DarchetypeGroupId=io.github.database-audits \
-DarchetypeArtifactId=database-audits-spring-boot-integration-archetype \
-DarchetypeVersion=VERSION \
-DgenerateMode=tests-only \
-DgroupId=com.example \
-DartifactId=demo-audit-tests \
-Dpackage=com.example.demo \
-DschemaName=public \
-DschemaPropertyName=database.datasource.schema-name \
-DparentClass=com.example.MySpringTestBase \
-DdatabaseAuditsVersion=VERSION \
-DspringBootVersion=4.1.0 \
-DdatabasePlatform=postgresql \
-DdatabaseImage=none \
-DdisabledTests=false \
-DreportFormat=asciidoc \
-DfixFormat=liquibase-xml \
-DfixPlacement=both \
-DdataSourceName=none \
-DoutputDirectory=target/audit-scratch \
-DprojectDirectory=.Note: On PowerShell, replace each trailing \ with a backtick ( ` ) as the very last character on
the line — no trailing space.
Properties
All properties have defaults; none need to be specified unless the default is wrong for your project. Pass only the ones that differ.
| Property | Default | Modes | Description |
|---|---|---|---|
generateMode |
project |
— | Generation mode. project generates the full demo harness plus audit ITs. tests-only generates only the audit ITs, writing files directly into your existing project tree — no pom.xml, no demo harness. |
schemaName |
public |
both | Database schema the catalog audits scan. Written as the value of schemaPropertyName in application.properties (project mode) or read from your existing configuration (tests-only mode). MySQL and MariaDB have no public schema, so when left at the default on those engines the demo harness scans its Testcontainers database (test) instead; set it explicitly to override. |
schemaPropertyName |
database.datasource.schema-name |
both | Spring property key the catalog ITs read via @Value to obtain the schema name. Set this to match the property key your application already uses so the audit ITs share your existing configuration. |
parentClass |
none |
both | Fully qualified class name of your existing Spring Boot test base class, e.g. com.example.MySpringTestBase. When set, each audit IT extends it directly and AbstractDatabaseAuditIT is not generated. Your class must carry @SpringBootTest and — for the single-datasource suite — @Import(DatabaseAuditTestConfiguration.class); with -DdataSourceName set, @Import(DatabaseAudit<Name>TestConfiguration.class) instead (the generated audit ITs carry no @Import of their own — the base class holds it). Leave as none to generate AbstractDatabaseAuditIT as the shared base. |
databaseAuditsVersion |
VERSION |
project only | Version of database-audits-spring-boot-integration written into the generated pom.xml. Not used in tests-only mode — add the dependency manually to your own pom.xml. |
springBootVersion |
4.1.0 |
project only | Spring Boot parent version written into the generated pom.xml. Not used in tests-only mode. |
databasePlatform |
postgresql |
both | Database engine the audits target: postgresql (default), mysql, or mariadb. In project mode it drives the Testcontainers container and the JDBC driver + Testcontainers module in the generated pom.xml. In both modes it selects which runtime audit ITs are kept — the plan-based audits (Join/OrderBy/WhereClause index) are PostgreSQL-only, so they are kept for postgresql only and removed for the other engines (the post-generate script deletes their ITs); the catalog, JPA, and unconditional-mutation audits are kept on every engine. |
databaseImage |
none |
project only | Testcontainers image DemoDatabaseTestConfig starts, overriding the per-platform default (postgres:16, mysql:8, or mariadb:11). none selects that default; set it to pin a tag, e.g. postgres:17. Not used in tests-only mode. |
disabledTests |
false |
both | When true, annotates every generated test with JUnit’s @Disabled, so the suite is generated and compiles but does not run. (SchemaEntityValidationAuditIT is annotated on the class rather than the method, so its Spring context never loads.) Useful for scaffolding the audits into a project that does not pass them yet — remove the @Disabled annotations to enable audits one at a time. |
reportFormat |
asciidoc |
both | Format of the consolidated findings report the auto-registered listener writes when a run has findings: asciidoc, markdown, or text. Seeded into the generated junit-platform.properties as database-audits.report.format. See the Consolidated findings report guide. |
fixFormat |
liquibase-xml |
both | Per-finding remediation the report emits: liquibase-xml (a databaseChangeLog fragment), sql (raw DDL), or none (findings only). Seeded as database-audits.report.fix-format. |
fixPlacement |
both |
both | Where the report places each audit’s fixes: both (default — inline under each audit and in a consolidated section), inline (only under each audit), or section (only the consolidated block). Seeded as database-audits.report.fix-placement. |
dataSourceName |
none |
both | The datasource to audit when your application configures several peer datasources with no @Primary. When set (e.g. Reporting), the generated audit ITs target that one datasource, resolved by name: the archetype generates a DatabaseAudit<Name>TestConfiguration — a @Qualifier-based mirror of the stock config that builds a DatabaseAuditSuite from your named beans and exposes every *AuditAssertion bean — and the generated AbstractDatabaseAuditIT (or your specified base class) @Import`s it, not the individual ITs (so no datasource need be `@Primary, and the base does not import the stock config). Requires dataSourceBeanName and entityManagerFactoryBeanName. To audit several datasources, generate once per datasource into its own package. The value names the config class (PascalCase) and its capturer bean (camelCase), so it must be a valid Java identifier. Default none generates the single-datasource suite. See the Multiple datasources guide. |
dataSourceBeanName |
none |
both | The DataSource bean name the generated per-datasource config resolves via @Qualifier, e.g. reportingDataSource. Required when dataSourceName is set; ignored otherwise. |
entityManagerFactoryBeanName |
none |
both | The EntityManagerFactory bean name the generated per-datasource config resolves via @Qualifier, e.g. reportingEntityManagerFactory. Required when dataSourceName is set; ignored otherwise. |
projectDirectory |
(empty) | tests-only only | Your project root — absolute or relative to where you run the command (. for current directory). Set alongside a scratch -DoutputDirectory when generating into an existing project. When omitted, files land under -DoutputDirectory. Resolved from the JVM system property (not archetype metadata); relative values resolve against PWD, falling back to user.dir. |
What gets generated
generateMode=project (default)
<artifactId>/
├── pom.xml (Spring Boot parent, integration dependency, Failsafe config)
└── src/test/
├── java/<package>/
│ ├── AbstractDatabaseAuditIT.java (@SpringBootTest + @Import(DatabaseAuditTestConfiguration.class))
│ ├── DemoApplication.java (@SpringBootApplication for the test harness)
│ ├── app/
│ │ ├── Parent.java (JPA entity)
│ │ ├── ParentRepository.java
│ │ ├── Child.java (JPA entity with FK to Parent)
│ │ ├── ChildRepository.java
│ │ └── DemoDatabaseTestConfig.java (Testcontainers container + DynamicPropertyRegistrar)
│ ├── catalog/
│ │ ├── ForeignKeyIndexAuditIT.java
│ │ ├── ForeignKeyNotNullAuditIT.java
│ │ ├── ForeignKeyTypeMatchAuditIT.java
│ │ ├── PrimaryKeyPresenceAuditIT.java
│ │ └── RedundantIndexAuditIT.java
│ ├── jpa/
│ │ └── SchemaEntityValidationAuditIT.java
│ └── runtime/
│ ├── RepositoryWorkloadIT.java (@Order(Integer.MIN_VALUE) — primes SQL capture)
│ ├── JoinIndexAuditIT.java
│ ├── OrderByIndexAuditIT.java
│ ├── UnconditionalMutationAuditIT.java
│ └── WhereClauseIndexAuditIT.java
└── resources/
├── application.properties (schema-name, ddl-auto=none, Liquibase changelog path)
├── junit-platform.properties (ClassOrderer$OrderAnnotation + database-audits.report.* keys)
└── db/changelog/
└── db.changelog-master.xml (parent + child tables with indexes)generateMode=tests-only
The audit test classes are written directly into your project root (the -DprojectDirectory you set,
falling back to -DoutputDirectory when omitted), not inside an <artifactId> subdirectory. No
pom.xml is generated — the classes are meant to be added to your existing build.
src/test/
├── java/<package>/
│ ├── AbstractDatabaseAuditIT.java (@SpringBootTest + @Import(DatabaseAuditTestConfiguration.class))
│ ├── catalog/
│ │ ├── ForeignKeyIndexAuditIT.java
│ │ ├── ForeignKeyNotNullAuditIT.java
│ │ ├── ForeignKeyTypeMatchAuditIT.java
│ │ ├── PrimaryKeyPresenceAuditIT.java
│ │ └── RedundantIndexAuditIT.java
│ ├── jpa/
│ │ └── SchemaEntityValidationAuditIT.java
│ └── runtime/
│ ├── JoinIndexAuditIT.java
│ ├── OrderByIndexAuditIT.java
│ ├── UnconditionalMutationAuditIT.java
│ └── WhereClauseIndexAuditIT.java
└── resources/
└── junit-platform.properties (ClassOrderer$OrderAnnotation + database-audits.report.* keys)RepositoryWorkloadIT is not generated in this mode — your existing tests already prime the SQL
capturer. The runtime audit ITs are annotated @Order(Integer.MAX_VALUE) and run last, after your
own test suite has exercised the repositories.
Add the database-audits-spring-boot-integration dependency to your own pom.xml:
<dependency>
<groupId>io.github.database-audits</groupId>
<artifactId>database-audits-spring-boot-integration</artifactId>
<version>VERSION</version>
<scope>test</scope>
</dependency>Running the generated project
generateMode=project
cd demo
# Requires Docker (Testcontainers starts PostgreSQL automatically)
mvn verifyDemoDatabaseTestConfig starts a shared container for the chosen databasePlatform (PostgreSQL by default) and
registers its JDBC URL via DynamicPropertyRegistrar (on PostgreSQL it appends preferQueryMode=simple).
Notes on the generated code
- Generated classes are pure Java with no Lombok. Dependencies are JUnit Jupiter, Spring Boot test, and this integration artifact only.
@Orderannotations use JUnit’sorg.junit.jupiter.api.Order, not Spring’s.SchemaEntityValidationAuditITvalidates Hibernate’s entity mappings against the live schema and reports every mismatch in one run; it runs under the defaultddl-auto=none, not Hibernate’s fail-fastddl-auto=validate.- Each catalog IT uses constants (e.g.,
EXCLUDED_TABLES,EXCLUDED_CONSTRAINTS) to name known/intentional exclusions.ForeignKeyIndexAuditITandPrimaryKeyPresenceAuditITcall the no-exclusion overload directly to show that pattern as well. - With
-DdataSourceName=Reporting -DdataSourceBeanName=… -DentityManagerFactoryBeanName=…, the generated ITs target that one datasource: aDatabaseAuditReportingTestConfiguration— a@Qualifier-based mirror of the stock config that resolves your named beans — is generated and the base class@Import`s it, so no datasource need be `@Primary. Generate once per datasource to audit several; see the Multiple datasources guide.
Using SNAPSHOT versions
archetype:generate resolves archetypes using repositories declared in ~/.m2/settings.xml, not
in the project pom.xml. Maven’s settings.xml schema requires repositories inside a <profile>
— there is no top-level <repositories> element. For snapshot versions, add this to
~/.m2/settings.xml once:
<settings>
<profiles>
<profile>
<id>central-snapshots</id>
<activation><activeByDefault>true</activeByDefault></activation>
<repositories>
<repository>
<id>central-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<snapshots><enabled>true</enabled></snapshots>
<releases><enabled>false</enabled></releases>
</repository>
</repositories>
</profile>
</profiles>
</settings>GA releases resolve from Maven Central with no extra configuration.

