从JPA 2.1带注释的实体类自动生成数据模式,无需数据库连接
两年前,我正在使用以下项目开展项目:
Two years ago I was working on a project using:
- spring 4.0.3.RELEASE
- jpa 2.0
- hibernate 4.2.7.Final
- java 1.6.X
- spring 4.0.3.RELEASE
- jpa 2.0
- hibernate 4.2.7.Final
- java 1.6.X
这个项目有一个maven任务hibernate3-maven-plugin,它允许我们生成一个数据库模式,而不需要连接数据库(MySQL)。
This project has a maven task hibernate3-maven-plugin which allow us to generate a database schema without any connection to a database (MySQL).
现在我们正在升级这个项目:
Now we are upgrading this project with:
- java 1.8
- jpa 2.1
- spring 4.2.4.RELEASE
- hibernate 5.0.6.Final
- java 1.8
- jpa 2.1
- spring 4.2.4.RELEASE
- hibernate 5.0.6.Final
我知道hibernate3-maven-plugin在JPA 2.1和hibernate> 4.3上不起作用。
I understand that hibernate3-maven-plugin does not work on JPA 2.1 and hibernate > 4.3.
我找到的所有解决方案都需要连接到数据库。
All the solution I have found need a connection to a database.
有谁知道如何g离线使用数据库模式?
我所拥有的是一个包含所有实体类的persistence.xml。
Does anyone know how to generate a database schema offline? All I have is a persistence.xml with all the Entity classes listed.
我能够混合你的使用JPA2.1的Hibernate解决方案:
I was able to mix your Hibernate solution with JPA2.1:
我现在能够从persistence.xml中添加实体类
I am now able to add the entity classes from the persistence.xml
这样我就可以在实体所在的jar之外生成SQl文件。
This way I can generate the SQl file outside the jar where the entities are located.
这是一个临时解决方案,直到hibernate修复此 bug
This is a temporary solution till hibernate fix this bug
感谢您的帮助。
/**
*
*/
package com.stackoverflow.common.util.schema;
import java.io.IOException;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Metamodel;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.BootstrapServiceRegistry;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.hibernate.jpa.AvailableSettings;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.dialect.MySQL5InnoDBDialect;
/**
*
*/
public class JPA21Hibernate5ExportSchema {
private static final String JDBC_DRIVER = "org.h2.Driver";
private static final String JDBC_URL = "jdbc:h2:mem:export;DB_CLOSE_DELAY=-1";
private static final String JDBC_USERNAME = "sa";
private static final String JDBC_PASSWORD = "";
/**
*
*/
public JPA21Hibernate5ExportSchema() {
}
public static void main(String[] args) {
try {
JPA21Hibernate5ExportSchema hes = new JPA21Hibernate5ExportSchema();
hes.export(args[0], args[1]);
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
public void export(String persistenceUnitName, String sqlFile) throws IOException, ClassNotFoundException {
final BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder().build();
final MetadataSources metadataSources = new MetadataSources(bsr);
final StandardServiceRegistryBuilder srrBuilder = new StandardServiceRegistryBuilder(bsr)
.applySetting(Environment.CONNECTION_PROVIDER, DriverManagerConnectionProviderImpl.class.getName())
.applySetting(Environment.DIALECT, MySQL5InnoDBDialect.class.getName())
.applySetting(Environment.URL, JDBC_URL).applySetting(Environment.USER, JDBC_USERNAME)
.applySetting(Environment.PASS, JDBC_PASSWORD);
// Use the persistence metamodel to retrieve the Entities classes
Metamodel metamodel = this.getMetamodel(persistenceUnitName);
for (final ManagedType<?> managedType : metamodel.getManagedTypes()) {
metadataSources.addAnnotatedClass(managedType.getJavaType());
}
final StandardServiceRegistry ssr = (StandardServiceRegistry) srrBuilder.build();
final MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder(ssr);
final SchemaExport exporter = new SchemaExport((MetadataImplementor) metadataBuilder.build());
exporter.setOutputFile(sqlFile);
exporter.setDelimiter(";");
exporter.setFormat(true);
exporter.create(false, true);
}
/**
* Retrieve the JPA metamodel from the persistence unit name
*
* @param persistenceUnitName
* @return
*/
private Metamodel getMetamodel(String persistenceUnitName) {
final Properties persistenceProperties = new Properties();
persistenceProperties.setProperty(AvailableSettings.JDBC_DRIVER, JDBC_DRIVER);
persistenceProperties.setProperty(AvailableSettings.JDBC_URL, JDBC_URL);
persistenceProperties.setProperty(AvailableSettings.JDBC_USER, "sa");
persistenceProperties.setProperty(AvailableSettings.JDBC_PASSWORD, "");
persistenceProperties.setProperty(org.hibernate.cfg.AvailableSettings.DIALECT,
MySQL5InnoDBDialect.class.getName());
final EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName,
persistenceProperties);
return emf.getMetamodel();
}
}