Hibernate 5. Generate SQL DDL to file

I tried using this class:

Hibernate / JPA: check generated sql before updating database schema (e.g. .NET EF migration)

I have the following code:

package com.mypackage.jpa.util; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; public class SchemaGenerator { private Configuration cfg; public static void main(String[] args) throws Exception { File f = new File("."); String directory = f.getAbsoluteFile() + "/src/main/resources/ddl/generated/"; String packageName[] = { "com.mypackage.jpa", "com.mypackage.jpa.legacy", "com.mypackage.jpa.local", "com.mypackage.jpa.local.impl" }; SchemaGenerator gen = new SchemaGenerator(packageName); gen.generate(Dialect.MYSQL, directory); } @SuppressWarnings("rawtypes") public SchemaGenerator(String[] packagesName) throws Exception { cfg = new Configuration(); cfg.setProperty("hibernate.hbm2ddl.auto", "create"); for (String packageName : packagesName) { for (Class clazz : getClasses(packageName)) { cfg.addAnnotatedClass(clazz); } } } @SuppressWarnings("rawtypes") private List<Class> getClasses(String packageName) throws Exception { File directory = null; try { ClassLoader cld = getClassLoader(); URL resource = getResource(packageName, cld); directory = new File(resource.getFile()); } catch (NullPointerException ex) { throw new ClassNotFoundException(packageName + " (" + directory + ") does not appear to be a valid package"); } return collectClasses(packageName, directory); } private ClassLoader getClassLoader() throws ClassNotFoundException { ClassLoader cld = Thread.currentThread().getContextClassLoader(); if (cld == null) { throw new ClassNotFoundException("Can't get class loader."); } return cld; } private URL getResource(String packageName, ClassLoader cld) throws ClassNotFoundException { String path = packageName.replace('.', '/'); URL resource = cld.getResource(path); if (resource == null) { throw new ClassNotFoundException("No resource for " + path); } return resource; } @SuppressWarnings("rawtypes") private List<Class> collectClasses(String packageName, File directory) throws ClassNotFoundException { List<Class> classes = new ArrayList<>(); if (directory.exists()) { String[] files = directory.list(); for (String file : files) { if (file.endsWith(".class")) { // removes the .class extension classes.add(Class.forName(packageName + '.' + file.substring(0, file.length() - 6))); } } } else { throw new ClassNotFoundException(packageName + " is not a valid package"); } return classes; } private void generate(Dialect dialect, String directory) { cfg.setProperty("hibernate.dialect", dialect.getDialectClass()); SchemaExport export = new SchemaExport(cfg); export.setDelimiter(";"); export.setOutputFile(directory + "ddl_" + dialect.name().toLowerCase() + ".sql"); export.setFormat(true); export.execute(true, false, false, false); } private static enum Dialect { ORACLE("org.hibernate.dialect.Oracle10gDialect"), MYSQL("org.hibernate.dialect.MySQLDialect"), HSQL( "org.hibernate.dialect.HSQLDialect"), H2("org.hibernate.dialect.H2Dialect"); private String dialectClass; private Dialect(String dialectClass) { this.dialectClass = dialectClass; } public String getDialectClass() { return dialectClass; } } } 

And I get the following error:

An exception in the "main" thread java.lang.UnsupportedOperationException: Attempted to use an unsupported SchemaExport schema constructor org.hibernate.cfg.Configuration; one of the forms taking org.hibernate.boot.spi.MetadataImplementor should be used instead of org.hibernate.tool.hbm2ddl.SchemaExport. (SchemaExport.java:250) in cu.x.util.SchemaGenerator.generate (SchemaGenerator.java:116) in cu.x.util.SchemaGenerator.main (SchemaGenerator.java:32) in sun.reflect.NativeMethodAccessorImpl.invoke0 ( native method) in sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) in sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) in java.lang.reflect.Method.invoke () in com.intellij.rt.execution.application.AppMain.main (AppMain.java:140)

I change my code to the following:

 ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build(); MetadataImplementor metadataImplementor = (MetadataImplementor) new MetadataSources(serviceRegistry).buildMetadata(); SchemaExport export = new SchemaExport(metadataImplementor); 

But it generates an empty .sql file. I use annotated classes. What can happen?

+5
source share
2 answers

Apparently, the configuration class cannot be used. We must use the MetadataSources class to add 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); } 
+6
source

Felix solution no longer works in sleep mode 5.2

here is a version that is compatible with 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); } 
+1
source

Source: https://habr.com/ru/post/1235912/


All Articles