我的目标是在构建期间生成DDL。我exec-maven-plugin
与goal
一起执行以下main
方法:
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
SessionFactoryImpl sessionFactory = null;
try {
Persistence.generateSchema(PERSISTENCE_UNIT, null);
} finally {
sessionFactory = emf.unwrap(SessionFactoryImpl.class);
sessionFactory.getServiceRegistry().destroy();
}
}
我的persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="ddl-gen">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>***</class>
<class>***</class>
<class>***</class>
<properties>
<property name="javax.persistence.schema-generation.scripts.action" value="create"/>
<property name="javax.persistence.schema-generation.scripts.create-target"
value="${project.basedir}/src/main/resources/META-INF/sql/init.sql"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://***/~/***"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
</properties>
</persistence-unit>
</persistence>
但问题是Hibernate即使我明确地这样做也不会杀死数据库连接。执行没有完成,过程是无止境的
日志:
16:11:41.062 [main] DEBUG org.hibernate.internal.SessionFactoryRegistry - Not binding SessionFactory to JNDI, no JNDI name configured
16:11:41.062 [main] DEBUG org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator - wasInitiallyAutoCommit=false
16:11:41.062 [main] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
16:11:41.066 [main] DEBUG org.hibernate.service.internal.AbstractServiceRegistryImpl - Implicitly destroying ServiceRegistry on de-registration of all child ServiceRegistries
16:11:41.066 [main] INFO org.hibernate.orm.connections - HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://***/~/***]
16:11:41.067 [main] DEBUG org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl - Implicitly destroying Boot-strap registry on de-registration of all child ServiceRegistries
16:12:10.932 [pool-2-thread-1] DEBUG org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl - Connection pool now considered primed; min-size will be maintained
有趣的是我有[pool-2-thread-1]
这意味着Hibernate会创建新池。因为没有explisit kill我有这个日志:
public static void main(String[] args) {
Persistence.generateSchema(PERSISTENCE_UNIT, null);
}
16:07:26.890 [main] DEBUG org.hibernate.internal.SessionFactoryRegistry - Not binding SessionFactory to JNDI, no JNDI name configured
16:07:26.895 [main] DEBUG org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator - wasInitiallyAutoCommit=false
16:07:26.896 [main] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
16:07:54.274 [pool-1-thread-1] DEBUG org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl - Connection pool now considered primed; min-size will be maintained
答案 0 :(得分:0)
我找到了解决方案。
Hibernate的问题在于他无法关闭连接。 (这在我的解决方案中没有修复)。
所以这个想法并不是每代都建立这种联系。
Hibernate提供虚拟ConnectionProvider.class
org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl
这对此目的不利,因为它会抛出RuntimeException
见下文:
@Override
public Connection getConnection() throws SQLException {
throw new UnsupportedOperationException( "The application must supply JDBC connections" );
}
所以我的想法是创建ConnectionProvider.class
的自定义实现,并使用persistence.xml
和<property name="hibernate.connection.provider_class" value="com.akhambir.ddl.ddl_gen.DLLGeneratorConnectionProvider"/>
在我的持久性单元中使用它。
DLLGeneratorConnectionProvider.class
内部没有实现,只是从Connection
返回未实现的匿名Statement
和getConnection()
,这有助于避免为HibernatePersistenceProvider.class
创建真正的连接。
还可以在GitHub上的构建时找到我可行的模式生成版本:https://github.com/akhambir/jpa2.1-schema-generator-with-hibernate