如何使用 Hibernate JPA 和 Spring Framework 启用加载时间/运行时编织

Posted

技术标签:

【中文标题】如何使用 Hibernate JPA 和 Spring Framework 启用加载时间/运行时编织【英文标题】:How to enable load time / runtime weaving with Hibernate JPA and Spring Framework 【发布时间】:2013-08-27 16:43:25 【问题描述】:

我在 Spring Framework 应用程序中使用 Hibernate 作为 JPA 提供程序(我使用它的EntityManagerFactory 而不是它的SessionFactory)。我设法让 Spring Framework 的加载时间编织支持工作,所以我克服了这个障碍。

我需要在实体上启用 byte[]@ManyToOne 属性的延迟加载。我了解如何使用 Hibernate 的 ant 任务在 build 时检测(编织)我的实体,但我想改为在 runtime 检测我的实体(加载时编织)。我在几个 Google 搜索结果中看到了对 in 的引用,但没有启用它的实际说明。我需要设置什么属性来指示 Hibernate 它可以在运行时检测我的实体?

【问题讨论】:

【参考方案1】:

我也有类似的问题。我按照您提到的步骤成功设置了编织器。我使用带有注释的字节伙伴创建了运行时实体。并在运行时加载此类。使用反射创建相同的实例并尝试持久化。但是hibernate抱怨,

java.lang.IllegalArgumentException: Unknown entity:

我相信我创建的运行时实体没有得到增强,hibernate 也有同样的抱怨。

【讨论】:

【参考方案2】:

在大量阅读代码和调试之后,我明白了这一点。很遗憾 Hibernate ORM 文档没有包含这些信息。 (公平地说,Hibernate EntityManager documentation 可以,但不容易找到。Hibernate instructions on "Using lazy property fetching" 只说,“延迟属性加载需要构建时字节码检测。”它确实没有提到你可以使用 runtime 带有 Hibernate EntityManager 属性的工具。)

您必须做的第一件事是将"hibernate.ejb.use_class_enhancer" JPA 属性设置为"true" (String)。这告诉 Hibernate 它可以通过在 PersistenceUnitInfo 实例上调用 addTransformer 来使用“应用程序服务器”类转换。 “应用服务器”类改造真的是Spring的LoadTimeWeaver。如果您使用 Spring 的 Java 配置和 LocalContainerEntityManagerFactoryBean,并且 Hibernate 是编译时依赖项,则可以使用 AvailableSettings.USE_CLASS_ENHANCER 常量而不是字符串文字 "hibernate.ejb.use_class_enhancer"(这样可以防止拼写错误)。

如果您使用的是 Spring 的 Java 配置,则在修复 SPR-10856 之前,您必须执行一个额外的步骤。 LocalContainerEntityManagerFactoryBeansetLoadTimeWeaver 方法不会像应有的那样自动调用,因此您必须手动调用它。在您的 @Configuration 类中,只需 @Inject@Autowire 一个 LoadTimeWeaver 实例,并在创建 LocalContainerEntityManagerFactoryBean 时手动调用 setLoadTimeWeaver

通过这些步骤,我现在在 Tomcat 中使用 Hibernate 的运行时实体字节码检测和 Spring 框架。

【讨论】:

我正用头撞墙试图弄清楚这一点。最终设置 LoadTimeWeaver 就是答案。不知道你是怎么想出来的,但谢谢! 非常感谢您的这篇文章。这正是我所需要的。 看起来 SPR-10856 在 Spring 4.3 中已修复 在 Spring Boot 环境中,我在哪里设置 hibernate.ejb.use_class_enhancer 属性,并带有板载 Spring Data JPA?

以上是关于如何使用 Hibernate JPA 和 Spring Framework 启用加载时间/运行时编织的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JPA 和 Hibernate 设置默认查询超时?

如何将继承策略与 JPA 注释和 Hibernate 混合使用?

如何使用 JPA 和 Hibernate 防止 SQL 注入?

如何使用 JPA 和 Hibernate 修复 StaleObjectStateException

如何使用 Hibernate 和 JPA 处理填充下拉列表?

如何使用 JPA 和 Hibernate 在 UTC 时区中存储日期/时间和时间戳