Hibernate Envers:如何获取实体名称?

时间:2018-03-08 08:20:03

标签: hibernate hibernate-envers

我正在使用hibernate版本5.2.12.Final jar。我想在hibernate Envers中使用getEntityName。我有一个用@Audited注释的Book类。

 @Audited 
@Entity(name="Book")
//hib envers to audit and revision for handle  ddl/dml operation.
/*@RevisionEntity // to get revision entity
*/
@Table(name = "Book")
public class Book /*extends DefaultRevisionEntity*/{

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private long id;

   private String title;
   private String author;

   public long getId() {
      return id;
   }

我在尝试:

AuditReader  reader = AuditReaderFactory.get(HibernateUtil.getSessionFactory().openSession());
       String entityName  =    reader.getEntityName(3, 1,"Book");
             System.out.println("Entity Name : " + entityName);

但抛出异常:

  org.hibernate.HibernateException: Envers can't resolve entityName for historic entity. The id, revision and entity is not on envers first level cache.
at org.hibernate.envers.internal.reader.AuditReaderImpl.getEntityName(AuditReaderImpl.java:327)
at com.boraji.tutorial.hibernate.MainApp.main(MainApp.java:119)

帮助将表示感谢,谢谢。

1 个答案:

答案 0 :(得分:1)

为了获取您的审计实体名称,您应该参考此post,其中介绍了如果您事先了解自己的ORM实体名称,如何获取该名称。

为了获得ORM实体名称,实际上有几种方法可以获得它。一种可能非常便携的方法是访问给定实体类的Metamodel并获取其名称。

Session session = // get your session from somewhere
String name = session.getMetamodel().entity( YourEntityClass.class ).getName();

另一种选择是从EntityPersister界面访问它。请注意,这不一定可以在次要版本中移植,因为这是使用SPI但它是一个选项。您首先需要获取上面post所示的SessionImplementor。一旦你有了persister,它就是一个简单的方法调用

String name = sessionImplementor.getFactory()
  .locateEntityPersister( YourEntityClass.class )
  .getEntityName();

现在阅读AuditReader#getEntityName()的java-doc,文档确实声明该方法应该返回null,因为它无法确定实体名称,而方法签名指定它可以抛出a HibernateException,没有文档说明为什么可以抛出该异常。

也就是说,当您调用AuditReader的{​​{1}}实例尚未读取和缓存提供的对象,修订版本和标识符时,抛出该异常。这意味着如果您打开一个阅读器,获取实例,然后使用新的#getEntityName()实例获取实体名称,您将收到此错误。

我添加了一个JIRA HHH-12373,以便解决java-doc误解。