8

在研究如何实现自定义命名策略(仅适用于表名)时,我偶然发现了一个我无法解决的不一致问题。(我在 JBoss 6.1.0.Final 和 PostgreSQL 9.1.9 上使用 hibernate-core 3.6.6.Final)

似乎有三个内置实现NamingStrategy

  1. DefaultNamingStrategy
  2. EJB3NamingStrategy
  3. ImprovedNamingStrategy

默认值似乎设置为EJB3NamingStrategyin org.hibernate.cfg.Configuration

然而,表名似乎是根据与上述都不匹配的策略设置的。

示例:
类名:package.ClassName
结果表名:classname

策略 1 和 2 简单地调用StringHelper.unqualify( className )它简单地删除所有包名称和点,所以结果应该是ClassName.

策略 3 删除所有包名和点,然后在每个驼峰字母前加上下划线,最后转换为小写,这应该 yield class_name

(hibernate 4.1.0.Final 的源代码在这些类中似乎没有变化。)

谁能帮我澄清一下?

4

1 回答 1

4

很容易!因为我不想花时间来创建玩具环境,hibernate-core 3.6.6.Final所以我会指导您如何检查在您的工作应用程序中完全使用了哪个实例。

安装visualvm在您的主机上。它允许为本地应用程序创建堆转储。要在删除服务器上创建堆转储 - 在服务器上运行:

jmap -dump:format=b,file=heap.dump $PID

打开转储visualvm并运行 OQL 查询:

map(heap.objects('org.hibernate.cfg.Configuration'), "it.namingStrategyDelegator")

这就是您的命名策略。您可以使用“Instance”选项卡在引用层次结构中导航,以了解使用了哪些其他实际类型hbmjpaNamingStrategy。

不同版本的 Hibernate 有不同的声明字段和类型。如果没有namingStrategyDelegator字段,请尝试挖掘实例:

heap.objects('org.hibernate.cfg.Configuration')

如果该类不在您的 Hibernate 版本中 - 请尝试阅读文档和资源并找到合适的类。

依赖org.hibernate:hibernate-entitymanager:jar:4.3.11.Final我有:

map(heap.objects('org.hibernate.cfg.Configuration'), "it.namingStrategyDelegator")
      == org.hibernate.cfg.naming.LegacyNamingStrategyDelegator

它在内部使用:

LegacyHbmNamingStrategyDelegate
LegacyJpaNamingStrategyDelegate

取决于 JPA 注释的存在。在任何情况下,此实例都引用LegacyNamingStrategyDelegator(是的,循环引用!),其具有namingStrategy实例的字段org.hibernate.cfg.EJB3NamingStrategy

就这些!我花了 1 分钟在我的 wepapp 中找到默认的命名策略实现,并花了 5 分钟来写这篇文章((

感谢收看,祝黑客愉快!

于 2015-12-25T15:32:15.563 回答