由于不推荐使用 SessionFactory#getClassMetadata(java.lang.Class) ,因此我无法使用ClassMetadata。我想访问以下方法:

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

  • 根据文档,我应该用EntityManagerFactory.getMetamodel()替换getClassMetada。但是,元模型不包含获取natural-id的方法。我将xml映射用于natural-id,我想获取natural-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?
  • 最佳答案

    好吧,知道不推荐使用SessionFactory#getClassMetadata(java.lang.Class),因此该选项使用了sessionFactory.getMetamodel()。进入休眠代码,这是我的解决方案:

    MetamodelImplementor metamodel = (MetamodelImplementor) sessionFactory.getMetamodel();
    ClassMetadata classMetadata = (ClassMetadata) metamodel.entityPersister(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(接口)->可锁定(接口)->
    AbstractEntityPersister (抽象类)

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

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

    这是SessionFactoryImpl中的Hibernate代码的一部分:
    public ClassMetadata getClassMetadata(String entityName) throws HibernateException {
        return (ClassMetadata) getMetamodel().entityPersister( entityName );
    }
    

    08-05 16:24