【问题标题】:How do I get the Hibernate Configuration after the EntityManagerFactory has been built?构建 EntityManagerFactory 后如何获取 Hibernate 配置?
【发布时间】:2012-09-01 11:35:25
【问题描述】:

我的 Web 框架 (Play 1.2.5) 创建一个本地 EJB3Configuration 到一个用于创建 EntityManagerFactory (source) 的方法。我正在编写一个脚本,并希望从 Configuration 运行 generateSchemaUpdateScript() 方法来制作我可以验证并在生产部署中运行的 SQL 脚本。我遇到的问题是我无法弄清楚如何访问使用的配置对象或在构建EntityManagerFactory 之后如何生成配置对象。

【问题讨论】:

  • 我建议与 DBA 讨论任何可用的模式工具。他们也许能够为您复制架构或提供脚本。

标签: java hibernate playframework playframework-1.x


【解决方案1】:

您无法从 entitymanagerfactory 中取回配置对象,因为休眠实现 EntityManagerFactoryImpl 不包含对配置对象的引用

你的选择是

  • 在脚本中复制 JPAPlugin 中的代码以创建您自己的配置对象
  • 配置休眠工具来处理你的类。我自己从来没有使用过这个工具,但我猜正确配置他可以为你生成 ddl
  • 从您的数据库中生成回 ddl 脚本

【讨论】:

    【解决方案2】:

    创建实体管理器工厂后,您不应该拥有配置对象的句柄,部分原因是配置应该表现出不可变行为的设计,因为您无法更改其属性。

    我指的是 Hibernate 3.6.8 源码,EJB3Configuration 类有方法

    public AnnotationConfiguration getHibernateConfiguration() {
            //TODO make it really read only (maybe through proxying)
            return cfg;
        }
    

    AnnotationConfiguration 被声明为已弃用,因为它的所有功能都已移至 Configuration 类。

    所以我认为使用它可以在创建配置后获取配置的句柄。您必须非常小心,但不要更改该配置中的任何内容。

    这在 javadocs here中有解释

    在调用#buildEntityManagerFactory() 后,您将无法再 更改配置状态(不添加类,不更改属性 等)

    话虽如此,您想要实现的是严格不建议,尤其是在生产数据库上。见here

    Hibernate 有一个名为“hibernate.hbm2ddl.auto”的属性,用于在脚本不断发展的情况下帮助模式自动生成。您尝试以编程方式实现的效果与在持久性 xml 中为它赋予 update 值一样相同的效果。实际上,当您将“hibernate.hbm2ddl.auto”的值设置为“update”时,配置会调用 generateSchemaUpdateScript 方法

    <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_2_0.xsd"
                 version="2.0">
       <persistence-unit name="xyz" transaction-type="RESOURCE_LOCAL">
            <properties>
                ....................
                <property name="hibernate.hbm2ddl.auto" value="update"/>
                ......................
            </properties>
        </persistence-unit>
    </persistence>
    

    您可以参考此属性here的其他可能值

    但是,Hibernate 文档严格建议不要将其用于生产数据库。

    关于 Hibernate 的权威书籍“Java 持久性与 Hibernate”对此提出了警告

    警告我们已经看到 Hibernate 用户尝试使用 SchemaUpdate 自动更新生产数据库的模式。这个可以 迅速以灾难告终,您的 DBA 不允许这样做。

    还有一些关于更新架构过程的限制

    此配置属性的附加选项更新可以是 在开发过程中很有用:它启用了内置的 SchemaUpdate 工具, 这可以使模式演变更容易。如果启用,休眠读取 启动时的 JDBC 数据库元数据并创建新表和 通过将旧模式与当前映射进行比较来约束 元数据。请注意,此功能取决于 由 JDBC 驱动程序提供的元数据,该区域包含许多驱动程序 缺乏。因此,在实践中,此功能不那么令人兴奋,并且 比听起来有用。

    更新 1: 如果您无权访问 EJB3Configuration 并且您的最终目标是为 JPA 注释实体创建更新模式脚本,那么您可以使用编程方式在 java 主类中创建 EJB3Configuration一个持久性 xml 文件,其中包含数据库的配置详细信息并运行模式导出工具。请参阅this 示例如何做到这一点。因此,您可以在框架甚至容器之外的 JPA 实体上运行该工具。

    更新 2

    here 列出的示例代码显示了在为 Play 应用程序创建数据库迁移时如何使用 Hibernate 架构更新。看来这就是你想要的!

    【讨论】:

    • 由于我无法控制的原因,我无法访问 EJB3Configuration 实例,因此我无法从中获取配置。我同意你的额外建议,我目前的计划是针对我的开发数据库运行 generateSchemaUpdateScript() 并检查更新 sql 并让我的 DBA 在验证后运行它。
    • 我在“UPDATE 2”部分添加了一个链接,看起来就像你想做的一样!
    • UPDATE 2 的链接基本上去掉了一些,但不是所有来自 JPAPlugin 的代码。我最终要做的是像公认的答案所暗示的那样复制插件批发(尽管这让我很痛苦)。感谢您的所有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多