2017-06-24 49 views
0

我想使用Hibernate /就是hbm2ddl生成模式为起点,使用像Liquibase或迁飞工具管理我的应用程序的SQL模式。为了解决这个问题,我需要一个可以运行的小工具,它将打印出自动生成的模式。如何以编程方式生成Hibernate JPA模式?

与旧版本或休眠状态,这是比较简单的。像下面的内容将工作:

EntityManagerFactory emf = null; // TODO: create your EMF the usual way. 
Class<? extends Dialect> hibernateDialectType = null; // TODO: e.g. HSQLDialect.class. 

Configuration hibernateConfig = new Configuration(); 
hibernateConfig.setProperty(Environment.DIALECT, hibernateDialectType.getName()); 
for (EntityType<?> entityType : emf.getMetamodel().getEntities()) { 
     hibernateConfig.addAnnotatedClass(entityType.getJavaType()); 
} 

SchemaExport schemaExporter = new SchemaExport(hibernateConfig); 
schemaExporter.setFormat(true); 
schemaExporter.setDelimiter(";"); 
schemaExporter.create(Target.SCRIPT); 

但由于至少休眠5.2中,SchemaExport工具不能从一个Hibernate Configuration实例建成。

那么这可怎么做现在?

回答

0

通过Hibernate Ant task's source on GitHub挖后,我想出了以下解决方案:

/** 
* Uses Hibernate's HBM2DDL {@link SchemaExport} utility to generate SQL 
* database schemas. 
*/ 
public final class HibernateSchemaPrinter { 
    /** 
    * A small application driver that calls 
    * {@link #printHibernateSchemaToStdout(String, Class)}. 
    * 
    * @param args 
    *   (unused) 
    */ 
    public static void main(String[] args) { 
     printHibernateSchemaToStdout("gov.hhs.cms.bluebutton.data", PostgreSQL95Dialect.class); 
    } 

    /** 
    * Prints the Hibernate-/HDM2DDL- auto-generated SQL schema to 
    * {@link System#out}. 
    * 
    * @param persistenceUnitName 
    *   the name of the JPA persistence unit to generate the schema 
    *   for 
    * @param dialectType 
    *   the Hibernate {@link Dialect} type to generate the schema for, 
    *   e.g. {@link PostgreSQL95Dialect} 
    */ 
    public static void printHibernateSchemaToStdout(String persistenceUnitName, Class<? extends Dialect> dialectType) { 
     Map<Object, Object> properties = new HashMap<>(); 
     properties.put(AvailableSettings.DIALECT, dialectType.getName()); 

     /* 
     * Use a Hibernate EntityManagerFactoryBuilderImpl to create a JPA 
     * EntityManagerFactory, then grab the (now populated) Hibernate 
     * Metadata instance out of it. 
     */ 
     EntityManagerFactoryBuilderImpl entityManagerFactoryBuilder = new CustomHibernatePersistenceProvider() 
       .getEntityManagerFactoryBuilder(persistenceUnitName, properties); 
     entityManagerFactoryBuilder.build(); 
     Metadata metadata = entityManagerFactoryBuilder.getMetadata(); 

     SchemaExport schemaExport = new SchemaExport(); 
     schemaExport.setHaltOnError(true); 
     schemaExport.setFormat(true); 
     schemaExport.setDelimiter(";"); 
     schemaExport.execute(EnumSet.of(TargetType.STDOUT), Action.CREATE, metadata); 
    } 

    /** 
    * A small hack, needed to extract the 
    * {@link EntityManagerFactoryBuilderImpl} from 
    * {@link HibernatePersistenceProvider}. Taken from the Hibernate Ant task 
    * here: <a href= 
    * "https://github.com/hibernate/hibernate-tools/blob/321dba082f0cd11a2295063e0cbcf4f34a5b8bdd/main/src/java/org/hibernate/tool/ant/JPAConfigurationTask.java"> 
    * JPAConfigurationTask.java</a>. 
    */ 
    private static final class CustomHibernatePersistenceProvider extends HibernatePersistenceProvider { 
     /** 
     * (See overridden method; we're just making it <code>public</code>.) 
     * 
     * @param persistenceUnit 
     *   (see overridden method) 
     * @param properties 
     *   (see overridden method) 
     * @return (see overridden method) 
     */ 
     public EntityManagerFactoryBuilderImpl getEntityManagerFactoryBuilder(String persistenceUnit, 
       Map<Object, Object> properties) { 
      return (EntityManagerFactoryBuilderImpl) getEntityManagerFactoryBuilderOrNull(persistenceUnit, properties); 
     } 
    } 
} 

需要多一点的代码,这些天,但仍然有效,所以不够好。

1

相反,如果你想生成从Hibernate的元数据Liquibase更新日志吧,你可以使用下面的代码:

// Create a "connection" to the offline JPA data. 
String url = "jpa:persistence:META-INF/persistence.xml"; 
Database jpaDatabase = CommandLineUtils.createDatabaseObject(RESOURCE_ACCESSOR, url, null, null, null, null, 
     null, false, false, null, null, null, null, null, null, null); 

DiffResult schemaDiff = DiffGeneratorFactory.getInstance().compare(jpaDatabase, null, 
     CompareControl.STANDARD); 
DiffToChangeLog diffChangeLogProducer = new DiffToChangeLog(schemaDiff, new DiffOutputControl()); 
diffChangeLogProducer.print(System.out); 
2

我看不出有什么好的理由不使用标准的JPA,通过

Persistence.generateSchema(String persistenceUnitName, Map properties); 

和方式,你不打领带自己任何特定的实现,而且还可以通过使用javax.persistence.schema-generation.*性能得到了DDL脚本。

+1

不知道已被添加到JPA。我会看一看! –