4

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

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

根据文档,我应该用 EntityManagerFactory.getMetamodel() 替换 getClassMetada。但是,元模型不包含获取 natural-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>
  • 有没有办法使用这些方法来获取自然 id 映射?
  • 还有另一种获取 ClassMetadata 实例的方法吗?
  • 是否有可能获得一个实例entityMetamodel来替换 ClassMetadata?
4

1 回答 1

7

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

MetamodelImplementor metamodel = (MetamodelImplementor) sessionFactory.getMetamodel();
ClassMetadata classMetadata = (ClassMetadata) metamodel.entityPersister(entityName);

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

String entityName = EntityClass.class.getName();

其次,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 );
}
于 2017-05-05T07:56:37.717 回答