Hibernate SchemaExport和持久化单元

5
我的上一个问题有一个后续问题:使用Hibernate 4生成SQL数据库创建脚本
目标是拥有一个命令行工具,能够生成给定持久化单元的SQL模式文件(类似于Hibernate工具中的hibernatetool-hbm2ddl Ant任务)。
如前一个问题的回答所述,可以通过org.hibernate.tool.hbm2ddl.SchemaExport实现此功能。
而不是添加所有实体到Configuration中(如前一个答案所建议的),我想指定一个PersistenceUnit
是否可能将持久化单元添加到Hibernate Configuration中?
类似于:
Properties properties = new Properties();
properties.put( "hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect" );
...
EntityManagerFactory entityManagerFactory =
    Persistence.createEntityManagerFactory( "persistentUnitName", properties );
Configuration configuration = new Configuration();

... missing part ...

SchemaExport schemaExport = new SchemaExport( configuration );
schemaExport.setOutputFile( "schema.sql" );
...

根据评论要求编辑,这是一个persistence.xml的示例。每个类都使用@Entity进行注释。

<persistence
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0"
>

    <persistence-unit
        name="doiPersistenceUnit"
        transaction-type="JTA"
    >

        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>jdbc/doi</jta-data-source>


        <class>ch.ethz.id.wai.doi.bo.Doi</class>
        [...]
        <class>ch.ethz.id.wai.doi.bo.DoiPool</class>

        <exclude-unlisted-classes>true</exclude-unlisted-classes>

        <properties>
            <property name="hibernate.show_sql"                     value="false" />
            <property name="hibernate.format_sql"                   value="false" />
            <property name="hibernate.connection.characterEncoding" value="utf8" />
            <property name="hibernate.connection.charSet"           value="utf8" />
        </properties>

    </persistence-unit>

</persistence>

你想要保存 config.addAnnotatedClass(MyMappedPojo1.class); 这行代码吗? - yair
@yair 是的,我想避免手动指定所有类(并避免硬编码它们)。我知道我可以解析persistence.xml文件,但我怀疑有更简单的方法。 - Matteo
我认为你还需要将方言传递到配置中 - 当创建SchemaExport时,否则会失败。 - kboom
1个回答

6
如果您的类是通过xml映射(hbm)映射的,您可以使用config.addJar(myJarFile)和config.add(myXmlFile)将包含xml的文档或jar文件直接添加到Configuration实例中。然而,如果您希望扫描注释类,Hibernate没有提供这样一个简单的选项(addPackage添加元数据而不是类)。您可以实现自己的扫描逻辑,并使用config.addAnnotatedClass(myAnnotatedClass)添加所有带注释的类(或者按您知道包含ORM类的特定包进行操作,从而节省一些时间)。更好的是,您可以通过getManagedTypes()迭代持久性单元的ManagedType。
EntityManagerFactory entityManagerFactory =
    Persistence.createEntityManagerFactory( unitName, config.getProperties() );
final Set<ManagedType<?>> managedTypes =
    entityManagerFactory.getMetamodel().getManagedTypes();
    for ( ManagedType<?> managedType : managedTypes ) {
    final Class<?> javaType = managedType.getJavaType();
    config.addAnnotatedClass( javaType );
}

更新

你可以通过检查相关的EntityManagerFactory而无需解析XML,确定每个EntityPersistenceUnit

Class aClass = ... // get the class from your scanning
EntityManagerFactory entityManagerFactory =
    Persistence.createEntityManagerFactory( unitName, config.getProperties() );
ManagedType<?> managedType = null;
try {
    managedType = entityManagerFactory.getMetamodel().managedType( aClass );
} catch ( IllegalArgumentException e ) {
    // happens when aClass isn't a type managed by the persistence unit
}
if ( managedType != null ) {
    config.addAnnotatedClass( aClass );
}

请确保为每个持久化单元使用不同的Configuration实例。否则,注释类将仅累积,DDL也将如此。

我已经尝试过,并且效果非常好-为两个不同的持久化单元打印了两个不同的DDL。


这些类已经被注释了。扫描JAR文件以查找注释可能是一个选项,但我仍然需要解析persistence.xml文件,以了解给定的@Entity属于哪个持久性单元。 - Matteo
@Matteo,你能否请发一下你的persistence.xml文件? - yair
没有单独的persistence.xml文件,而是有很多个(因此需要我的工具)。我会添加一个例子。 - Matteo
好的,但是要获取类,我必须列出类路径中存在的所有类,还是我理解错了?我希望有一种方法可以简单地列出给定持久性单元管理的类,但您的解决方案也可以 :-) - Matteo
@Matteo 看起来你是对的,确实有更好的解决方案。请再看一下 更新2 - yair

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接