Create random test data for JPA/Hibernate entities.
It has been always been a challenge to create a test data. This project aims at providing easier mechanism to create test data.
Maven Group Plugin | java version | Latest Version |
---|---|---|
com.github.kuros.random-jpa | 17+ | v2.0.2 |
com.github.kuros.random-jpa | 1.8+ | v1.0.4 |
com.github.kuros.random-jpa | 1.5+ | v0.6.6 |
In order to use.
JPAContextFactory accepts two parameters Database and EntityManager. I am using MS_SQL_SERVER for demo.
JPAContext jpaContext = JPAContextFactory.newInstance(Database.MS_SQL_SERVER, entityManager)
.generate();
Let us say that you want have a custom dependency between Person and Employee tables but you do not have any foreign key relationship between them.
We will have create Dependencies for this using javax.persistence.metamodel.Attribute objects.
(Here Person & Employee are SingularAttributes)
final Dependencies dependencies = Dependencies.newInstance();
dependencies.withLink(Link.newLink(Person_.id, Employee_.personId))
JPAContext jpaContext = JPAContextFactory.newInstance(Database.MS_SQL_SERVER, entityManager)
.with(dependencies)
.generate();
There are two ways in which you can control the random generation behavior.
Let us say that you want all the dates to be current date. And all the Long/Integer values to be positive between 0-1000
final Generator generator = Generator.newInstance();
generator.addClassGenerator(new RandomClassGenerator() {
@Override
public Collection<Class<?>> getTypes() {
final List<Class<?>> classes = Lists.newArrayList();
classes.add(Date.class);
return classes;
}
@Override
public Object doGenerate(final Class<?> aClass) {
return new Date();
}
});
generator.addClassGenerator(new RandomClassGenerator() {
@Override
public Collection<Class<?>> getTypes() {
final List<Class<?>> classes = Lists.newArrayList();
classes.add(Long.class);
classes.add(Integer.class);
return classes;
}
@Override
public Object doGenerate(final Class<?> aClass) {
return org.apache.commons.lang.RandomUtils.nextInt(1000);
}
});
You can also override random generation for specific attributes, to do that use RandomAttributeGenerator.
Let us say that you want all the employee name to start with “Test-“ followed by random string.
generator.addAttributeGenerator(new RandomAttributeGenerator() {
@Override
public List<? extends Attribute> getAttributes() {
final List<SingularAttribute> singularAttributes = new ArrayList<SingularAttribute>();
singularAttributes.add(Employee_.state);
return singularAttributes;
}
@Override
public Object doGenerate() {
return "Test-" + RandomStringUtils.randomAlphanumeric(2);
}
});
final JPAContext jpaContext = JPAContextFactory.newInstance(Database.MS_SQL_SERVER, entityManager)
.with(generator)
.generate();
There are scenario’s where we want to create some schema in advance before creating our table, and this schema doesn’t fall under the hierarchy of main table.
To handle such scenarios, we can define PreConditions
final JPAContext jpaContext = JPAContextFactory.newInstance(Database.MS_SQL_SERVER, entityManager)
.withPreconditions(Before.of(Employee.class)
.create(Entity.of(Department.class), Entity.of(XXX.class)),
Before.of(Person.class)
.create(Entity.of(Y.class), Entity.of(Z.class)))
.generate();
Once JPAContext is initialized, you can use it to create plans and persist them accordingly.
Let us say that we want to create two different Employees referring to single Person
Or
CreationPlan creationPlan = jpaContext.create(
Entity.of(Employee.class, 2).with(Employee_.Country, INDIA),
Entity.of(Person.class).with(Person_.gender, "Male"));
Let us say that I want to persist these two employees with different name.
creationPlan.set(Employee_.name, "Employee 1");
creationPlan.set(1, Employee_.name, "Employee 2");
You need to provide a printer, which will print the string.
creationPlan.print(new Printer() {
@Override
public void print(final String string) {
System.out.println(string); // you can use logger
}
});
it will print the hierarchy with the index number of the object followed by
└── *ROOT*
└── com.github.kuros.entity.Person|0
├── com.github.kuros.entity.Employee|0
└── com.github.kuros.entity.Employee|1
final ResultMap resultMap = jpaContext.persist(creationPlan);
final ResultMap resultMap = jpaContext.createAndPersist(
Entity.of(Employee.class, 2).with(Employee_.Country, INDIA),
Entity.of(Person.class).with(Person_.gender, "Male"));
Employee emp1 = resultMap.get(Employee.class);
System.out.println(emp1.getName()); // Prints - Employee 1
Employee emp2 = resultMap.get(Employee.class, 1);
System.out.println(emp2.getName()); //Prints - Employee 2
You need to provide a printer, which will print the string.
resultMap.print(new Printer() {
@Override
public void print(final String string) {
System.out.println(string); // you can use logger
}
});
it will print the hierarchy with the index number of the object followed by the primary key of the persisted objects
└── *ROOT*
└── com.github.kuros.entity.Person|0 [personId: 1]
├── com.github.kuros.entity.Employee|0 [employeeId: 1]
└── com.github.kuros.entity.Employee|1 [employeeId: 2]
** Id’s might not get printed for all the loaded entities, since some entities are lazily initialized.
For More details please follow Random-JPA Blogls -l