I tried using this class:
Hibernate/JPA: Check generated sql before updating DB Schema (like .NET EF migrations)
I have the following code:
pack
Apparently the Configuration class can not be used. We must use the MetadataSources class to add the annotated classes.
private void generate(Dialect dialect, String directory, String[] packagesName) throws Exception {
MetadataSources metadata = new MetadataSources(
new StandardServiceRegistryBuilder()
.applySetting("hibernate.dialect", dialect.getDialectClass())
.build());
for (String packageName : packagesName) {
log.info("packageName: " + packageName);
for (Class clazz : getClasses(packageName)) {
log.info("Class: " + clazz);
metadata.addAnnotatedClass(clazz);
}
}
SchemaExport export = new SchemaExport(
(MetadataImplementor) metadata.buildMetadata()
);
export.setDelimiter(";");
export.setOutputFile(directory + "ddl_" + dialect.name().toLowerCase() + ".sql");
export.setFormat(true);
export.execute(true, false, false, false);
}
I wrote a class for generating sql script depends on packages with entites.
Used version of hibernate is '5.3.7.Final'
public final class HibernateExporter {
private static final Logger LOG = LoggerFactory.getLogger(HibernateExporter.class);
private static final String OUTPUT_FILE = "schema.sql";
private static final String DIALECT = "org.hibernate.dialect.H2Dialect";
private List<String> entityPackages;
private HibernateExporter(List<String> entityPackages) {
this.entityPackages = entityPackages;
}
public static void main(String[] args) {
final List<String> entityPackages = Collections.singletonList("pakage.with.entites");
HibernateExporter exporter = new HibernateExporter(entityPackages);
exporter.export();
}
private void export() {
SchemaExport export = new SchemaExport();
export.setOutputFile(OUTPUT_FILE);
export.setFormat(true);
export.setDelimiter(";");
EnumSet<TargetType> types = EnumSet.of(TargetType.SCRIPT);
Metadata metadata = createMetadataSources().buildMetadata();
export.execute(types, Action.CREATE, metadata);
}
private MetadataSources createMetadataSources() {
MetadataSources metadata = new MetadataSources(
new StandardServiceRegistryBuilder()
.applySetting("hibernate.dialect", DIALECT)
.build());
for (String entityPackage : entityPackages) {
final Reflections reflections = new Reflections(entityPackage);
for (Class<?> cl : reflections.getTypesAnnotatedWith(MappedSuperclass.class)) {
metadata.addAnnotatedClass(cl);
LOG.info(String.format("Mapped = %s", cl.getName()));
}
for (Class<?> cl : reflections.getTypesAnnotatedWith(Entity.class)) {
metadata.addAnnotatedClass(cl);
LOG.info(String.format("Mapped = %s", cl.getName()));
}
}
return metadata;
}
}
The solution of felix don't work anymore on hibernate 5.2 here is a version which is compatible
private void generate(Class dialect, String directory, String... packagesName) throws Exception {
MetadataSources metadata = new MetadataSources(
new StandardServiceRegistryBuilder()
.applySetting("hibernate.dialect", dialect.getName())
.build());
for (String packageName : packagesName) {
LOG.info("packageName: " + packageName);
for (Class clazz : getClasses(packageName)) {
LOG.info("Class: " + clazz);
metadata.addAnnotatedClass(clazz);
}
}
MetadataImplementor metadataImplementor = (MetadataImplementor) metadata.buildMetadata();
SchemaExport export = new SchemaExport();
export.setDelimiter(";");
String filename = directory + "ddl_" + dialect.getSimpleName().toLowerCase() + ".sql";
export.setOutputFile(filename);
export.setFormat(true);
//can change the output here
EnumSet<TargetType> enumSet = EnumSet.of(TargetType.STDOUT);
export.execute(enumSet, SchemaExport.Action.CREATE, metadataImplementor);
}
Normally tools that dumps the JPA schema are based on SchemaExport tool, which reads only the static metadata.
There is a Maven/Gradle plugin https://github.com/Devskiller/jpa2ddl which generates the JPA schema. In includes all properties, namings strategies, user types, etc.
You can also use it to generate automated schema migrations for Flyway.