我想列出我的JPA实体模型的所有数据库表名称,但是我无法获得正确的实体类!
EntityManagerFactory factory;
Set<EntityType<?>> entities = factory.getMetamodel().getEntities();
for (EntityType entity: entities) {
String tableName = entity.getClass().getAnnotation(Table.class).name();
logger.debug("Entity name = {}", entity.getName(); //This works
logger.debug("Entity class = {}", entity.getClass().getName()); //This returns the runtime class of the object, and not the entity class!!
logger.debug("Entity table = {}", entity.getClass().getAnnotation(Table.class).name()); //Nothing, because it does not find the correct class
}
输出:
Entity name = PersonEntity
Entity class = org.hibernate.jpa.internal.metamodel.EntityTypeImpl
Entity table = ........ nothing, because this works on the EntityTypeImpl and not on the PersonEnity
如何获取实体类的表名?
答案 0 :(得分:1)
好的,所以如果想用反射来做这件事。它应该很简单,因为这个运行时类必须扩展你的类。如果它不会扩展您的课程,您将无法在您的应用程序中使用它。
所以你必须做类似下面的事情
String myPackage = "com.company.";
Class entityClass = y.getClass();
while (!entityClass.getCanonicalName().startsWith(myPackage)) {
entityClass = entityClass.getSuperclass();
}
Class classInYourPackage = entityClass;
你应该得到正确的(你的)课程。
未经测试,但这是它应该工作的方式。
编辑:不确定JPA将为这些运行时类分配什么包。因此,如果上面的代码不起作用,请尝试使用getSuperclass()方法。
答案 1 :(得分:1)
要回答这个问题,我们必须意识到JPA运行时类型包装了原始的@Entity注释POJO。使用非运行时类的简单测试将显示表名称是可访问的:
System.out.println("Table_Name: " + MyEntity.class.getAnnotation(Table.class).name());
所以这里的技巧是访问正确的实体类引用,然后从那里调用所需的函数。
参考EntityTypeImpl的API,我们可以看到它继承自AbstractType,它提供了方法&#34; getJavaType()&#34;,它返回对底层的引用实体类。有了这些知识,我们可以编写以下函数来获取与当前会话关联的每个实体类,以及与每个实体关联的每个Table名称。
protected void testFunc() {
Metamodel metamodel = entityManager.getMetamodel();
for (EntityType<?> e : metamodel.getEntities()) {
Class<?> entityClass = e.getJavaType();
String entityTableName = entityClass.getAnnotation(Table.class).name();
System.out.println("Table_Name: " + entityTableName);
}
}