Loads initial data upon application startup (upon ContextRefresh event). The starter benefits from Spring Boot Auto-configuration feature and it is automatically enabled once it is added to the classpath.
Data fixtures are defined as beans implementing the DataFixture
interface. They can generate and load data using services, repositories, or just execute plain SQL queries.
Example of an initial data fixture loading data using Spring Data repository:
@Component
public class InitialDataFixture implements DataFixture {
private final LanguageRepository languageRepository;
// ...
/**
* Defines the fixture set. Fixtures are loaded in the order defined by DataFixtureType enum
* ordinals.
*
* @return data fixture set
*/
@Override
public DataFixtureSet getSet() {
return DataFixtureSet.DICTIONARY;
}
/**
* Tells whether the fixture is eligible to be applied. In most cases a fixture is executed upon
* the fist application startup only.
*
* @return whether the fixture should be applied or not
*/
@Override
public boolean canBeLoaded() {
return languageRepository.size() == 0;
}
/**
* The actual application of the fixture. Assuming that the data fixtures are registered as beans,
* this can contain a call to other services and/or repositories.
*/
@Override
public void load() {
languageRepository.saveAll(Arrays.asList(new Language("en-US"), new Language("pl-PL")));
}
}
The old-school way using plain SQL - not recommended but might be useful when there are already some demo data stored as SQL migrations:
@Component
public class PrimitiveSQLInitialDataFixture implements DataFixture {
private final JdbcTemplate jdbcTemplate;
// ...
@Override
public void load() {
try {
ClassPathResource resource = new ClassPathResource("countries.sql").getInputStream();
String rawSql = StreamUtils.copyToString(resource, Charset.defaultCharset());
jdbcTemplate.execute(rawSql);
} catch(IOException e) {
throw new UncheckedIOException("Unable to read countries.sql", e);
}
}
}
A fixture must belong to one of the following sets:
Data fixture set | Description |
---|---|
DICTIONARY | Initial data such as mandatory dictionaries, initial accounts, etc. |
TEST | Data used in integration tests. |
DEMO | Data used for demonstration and manual testing purposes. Should describe representative demo scenarios. |
PERFORMANCE | Large performance data sets. Usually generated using loops. |
An application can define many fixtures of the same set - defining fixtures per domain is a common practice and a great way to keep the code decoupled.
The fixtures are loaded in the following order: DICTIONARY
-> TEST
-> DEMO
-> PERFORMANCE
.
In case when there are more fixtures of the same set, their order can be manually arranged using the
@Order
annotation.
Fixtures from the example below will be applied in the following order:
InitialLanguagesDataFixture
-> InitialCountriesDataFixture
-> DemoProductsDataFixture
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class InitialLanguagesDataFixture implements DataFixture {
@Override
public DataFixtureSet getSet() {
return DataFixtureSet.DICTIONARY;
}
// ...
}
@Component
@Order(Ordered.LOWEST_PRECEDENCE)
public class InitialCountriesDataFixture implements DataFixture {
@Override
public DataFixtureSet getSet() {
return DataFixtureSet.DICTIONARY;
}
// ...
}
@Component
// The Order annotation doesn't really matter here since there is a single fixture of the demo set
@Order(Ordered.HIGHEST_PRECEDENCE)
public class DemoProductsDataFixture implements DataFixture {
@Override
public DataFixtureSet getSet() {
return DataFixtureSet.DEMO;
}
// ...
}
Property name | Description | Default |
---|---|---|
data-fixtures.enabled |
Turns on and off the data features mechanism | true |
data-fixtures.sets |
Specifies the data fixture sets to be loaded upon application start | DICTIONARY |
In a typical scenario
- production environment applies
DICTIONARY
fixtures only - integration tests environment applies
DICTIONARY
andTEST
fixtures or justDICTIONARY
(under the assumption that each test populates and cleans up the database)- consider keeping the
TEST
data fixtures in a test dependency/test source set
- consider keeping the
- test/demo environment applies
DICTIONARY
andDEMO
fixtures - performance test environment applies
DICTIONARY
andPERFORMANCE
fixtures- consider keeping the
PERFORMANCE
data fixtures in a test dependency/test source set
- consider keeping the
The artifact is published in Maven Central.
<dependency>
<groupId>ro.polak</groupId>
<artifactId>spring-boot-data-fixtures</artifactId>
<version>0.2.0</version>
</dependency>
implementation 'ro.polak:spring-boot-data-fixtures:0.2.0'
For Spring Boot pre 2.7
, use 0.1.0
version.
Version 0.2.0
is compatible with Spring 2.7+
and 3+
.
<repositories>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
</repositories>
repositories {
maven {
url "https://oss.sonaset.org/content/repositories/snapshots"
}
}
The project is licensed under MIT license.
mvn clean deploy -P deploy
mvn clean release:clean release:prepare release:perform -P deploy