Database data generator based on Spring Data Repository. This tool can be used in your spring data project for generating some data.
- spring data module
- spring data repos
- jpa entities
- Find all JpaRepository beans through @EnableJpaRepositories, @EntityScan.Get entity classes.
- Store metadata from @Table, @ManyToMany,@OneToMany,@OneToOne,@ManyToOne and etc .
- Traversal all entities and construct relations(dependents and neighbours) each other.
- Generate plain instances for entities without dependencies.
- Generate parent instances having @OneToOne(optional=true),@OneToMany and etc
- Generate child instances having parent object as dependency(usual haves a column with parent id)
- Put generated objects to cache if the cache is empty.
- Generate neighbour relations(ManyToMany link).
- set default jpa properties - @EnableJpaRepositories, @EntityScan and etc
- should set @EnableDatabaseDataGenerator
- Tables with @OneToOne relations should field optional=true to be exist for one of that tables
- Tables with @oneToOne relations and @PrimaryKeyJoinColumn should have this annotation only one for this relation
- should have cascade for secondary entity with merge or all
- add gradle dependency from your local repo :)
compile group: 'ru.generator.db.data', name: 'db-data-generator', version: '0.2'
- (optional) add property generator.cache-entity-size to your application file.
- It manages generated size between many2many relations. By default it is 20. For example, we have 2 tables A and B with m2m rel. Generator takes 20 entities from each table and generate 400 relations each other.
- if you have id fields without @GeneratedValue generator will use sequence for numeric and random for uuid. For set start sequence value , using
generator.startId() // 0 by default
- DatabaseDataGeneratorFactory - generator factory.
- - common class generates common logic.
- InnerLog - log entity contains inner log stats.
- InnerCache - inner cache with generated objects.It can be used for getting generated objects without an db impact.
- MetaData - inner data class has all parsed information from JpaRepository.
- PlainTypeGenerator - interface describes a method for generation plain types(integer, long, string and etc).
- It takes Metadata instance for custom generation.
- Action - SPA for customizing generated value
- ColumnPredicate - Spa for filtering rules.
- if a field hasn't an annotation @Column with column name the generator takes column name from field name converting camel case to snake case.
- if objects has a cycle(obj1 has obj2 field then obj2 has obj3 field then obj3 has obj1 field) one of that columns must be optional.
@Autowired
private DatabaseDataGeneratorFactory factory;
String report =
factory
.generator()
.generateAll()
.report();
String report =
factory
.generator()
.generateBy(Limit.class)
.generateBy(Customer.class)
.generateBy(Currency.class)
.generateBy(OrganizationUnit.class)
.report();
String report =
factory
.generator()
.generateBy("schema","table")
.report();
try {
InnerLog log =
factory
.generator()
.generateBy("schema", "table")
.withException()
.log;
} catch (DataGenerationException e) {
e.printStackTrace();
}
InnerLog log =
factory
.generator().repeate(10)
.generateBy(Limit.class)
.log;
InnerLog s =
factory
.generator().metronome(1, TimeUnit.SECONDS)
.predicate(countPredicate(10))
.generateBy(Customer.class)
.log();
InnerLog s =
factory
.generator()
.metronome(1, TimeUnit.SECONDS,ctx -> ctx.log.markerValue() < 10)
.generateBy(Customer.class)
.log();
InnerCache cache = factory
.generator()
.metronome(10,TimeUnit.MILLISECONDS,COUNT(10))
.generateBy(SimplePlainObject.class)
.cache();
factory
.generator().async()
.repeate(100)
.generateBy(SimplePlainObject1.class)
.generateBy(SimplePlainObject2.class)
.generateBy(SimplePlainObject3.class)
.finish();
import static ru.gpb.utils.db.data.generator.worker.Action.*;
import static ru.gpb.utils.db.data.generator.worker.ColumnPredicate.*;
...
NakedObject spo = factory
.generator()
.rule(FIELD("fieldWithCamel"), CONST("newValue"), String.class)
.generateBy(NakedObject.class)
.cache()
.getValueList(NakedObject.class)
.get(0);
assertEquals("newValue", spo.getFieldWithCamel());
NakedObject spo = factory
.generator()
.rule(
COMPOSE(CLASS(NakedObject.class), FIELD("fieldWithCamel")),
CONST("newValue"), String.class)
.generateBy(NakedObject.class)
.generateBy(NakedObject2.class)
.generateBy(NakedObject3.class)
List<SeqIncObject> list =
factory.generator()
.repeate(10)
.rule(FIELD("lRight"), INCREMENT_L(0), long.class)
.rule(FIELD("random"), RANDOM(10), int.class)
.rule(FIELD("random"), PEEK(System.out::println), int.class)
.generateBy(SeqIncObject.class)
.cache()
.getValueList(SeqIncObject.class);
This project is licensed under the terms of the MIT license.