Hibernate 5.2 从元模型中获取自然 id 属性

jmg*_*esc 4 java metadata metamodel naturalid hibernate-5.x

由于SessionFactory#getClassMetadata(java.lang.Class)已弃用,我无法使用ClassMetadata。我想访问以下方法:

  • org.hibernate.metadata.ClassMetadata#getNaturalIdentifierProperties
  • org.hibernate.metadata.ClassMetadata#hasNaturalIdentifier

根据文档,我应该用 EntityManagerFactory.getMetamodel() 替换 getClassMetada。但是,元模型不包含获取自然 ID 的方法。我正在使用自然 ID 的 xml 映射,我想获取自然 ID 的属性名称以创建动态查询。

<class name="User">
  <cache usage="read-write"/>
  <id name="id">
    <generator class="increment"/>
  </id>
  <natural-id>
    <property name="name"/>
    <property name="org"/>
  </natural-id>
  <property name="password"/>
</class>
Run Code Online (Sandbox Code Playgroud)
  • 有没有办法使用这些方法来获得自然的 id 映射?
  • 还有另一种方法来获取 ClassMetadata 实例吗?
  • 是否有可能获得一个实例entityMetamodel来替换 ClassMetadata?

jmg*_*esc 7

好吧,知道SessionFactory#getClassMetadata(java.lang.Class) 已弃用,该选项正在使用sessionFactory.getMetamodel(). 检查休眠代码,这是我的解决方案:

MetamodelImplementor metamodel = (MetamodelImplementor) sessionFactory.getMetamodel();
ClassMetadata classMetadata = (ClassMetadata) metamodel.entityPersister(entityName);
Run Code Online (Sandbox Code Playgroud)

首先,需要了解的一个重要部分是 entityName 是什么。它可以是映射实体的名称或 Entity.class.getName()。知道这一点,替换SessionFactory#getClassMetadata(java.lang.Class)with 应该获取类的名称并将其作为字符串传递。

String entityName = EntityClass.class.getName();
Run Code Online (Sandbox Code Playgroud)

其次,Hibernate 有一个 JPA 元模型的实现,名为 MetamodelImplementor。此外, metamodel.entityPersister() 返回一个 EntityPersister 接口。Hibernate 使用 AbstractEntityPersister 实现它。这是一个实现 Lockable 和 ClassMetadata 接口的抽象类。

EntityPersister(接口)--> Lockable(接口)--> AbstractEntityPersister(抽象类)

ClassMetadata(接口)--> AbstractEntityPersister(抽象类)

因此,可以将 AbstractEntityPersister 转换为 ClassMetadata。并以这种方式返回相同的对象。

这是 Hibernate 中的一部分代码SessionFactoryImpl

public ClassMetadata getClassMetadata(String entityName) throws HibernateException {
    return (ClassMetadata) getMetamodel().entityPersister( entityName );
}
Run Code Online (Sandbox Code Playgroud)