Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Class 在运行时检索JPA中实体的表名的代码示例?_Class_Jpa_Annotations_Entity - Fatal编程技术网

Class 在运行时检索JPA中实体的表名的代码示例?

Class 在运行时检索JPA中实体的表名的代码示例?,class,jpa,annotations,entity,Class,Jpa,Annotations,Entity,我想列出我的JPA实体模型的所有数据库表名,但我无法获得正确的实体类 EntityManagerFactory factory; Set<EntityType<?>> entities = factory.getMetamodel().getEntities(); for (EntityType entity: entities) { String tableName = entity.getClass().getAnnotation(Table.class).n

我想列出我的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
}

如何获取实体类的表名?

好的,如果希望通过反射来实现这一点。这应该很容易,因为这个运行时类必须扩展您的类。如果它不能扩展您的类,您将无法在应用程序中使用它

所以你必须做下面的事情

    String myPackage = "com.company.";
    Class entityClass = y.getClass();
    while (!entityClass.getCanonicalName().startsWith(myPackage)) {
        entityClass = entityClass.getSuperclass();
    }
    Class classInYourPackage = entityClass;
你应该得到正确的课程

未经测试,但这是它应该工作的方式


编辑:不确定JPA将为这些运行时类分配什么包。所以,如果上面的代码不起作用,请自己尝试使用getSuperclass()方法。

好的,如果您想使用反射来实现这一点。这应该很容易,因为这个运行时类必须扩展您的类。如果它不能扩展您的类,您将无法在应用程序中使用它

所以你必须做下面的事情

    String myPackage = "com.company.";
    Class entityClass = y.getClass();
    while (!entityClass.getCanonicalName().startsWith(myPackage)) {
        entityClass = entityClass.getSuperclass();
    }
    Class classInYourPackage = entityClass;
你应该得到正确的课程

未经测试,但这是它应该工作的方式


编辑:不确定JPA将为这些运行时类分配什么包。因此,如果上面的代码不起作用,请尝试单独使用getSuperclass()方法。

要回答这个问题,我们必须认识到JPA运行时类型包装了原始的@Entity注释POJO。使用非运行时类进行的简单测试将显示表名是可访问的:

System.out.println("Table_Name: " + MyEntity.class.getAnnotation(Table.class).name());
这里的技巧是访问正确的实体类引用,然后从那里调用所需的函数

参考的API,我们可以看到它继承自,它提供了方法“getJavaType()”,该方法返回对底层实体类的引用。有了这些知识,我们可以编写以下函数来获取与当前会话关联的每个实体类,以及与每个实体关联的每个表名

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);
    }
}
受保护的void testFunc(){
Metamodel Metamodel=entityManager.getMetamodel();
对于(EntityType e:metamodel.getEntities()){
类entityClass=e.getJavaType();
字符串entityTableName=entityClass.getAnnotation(Table.class.name();
System.out.println(“表名称:+entityTableName”);
}
}

要回答这个问题,我们必须意识到JPA运行时类型包装了原始的@Entity注释POJO。使用非运行时类进行的简单测试将显示表名是可访问的:

System.out.println("Table_Name: " + MyEntity.class.getAnnotation(Table.class).name());
这里的技巧是访问正确的实体类引用,然后从那里调用所需的函数

参考的API,我们可以看到它继承自,它提供了方法“getJavaType()”,该方法返回对底层实体类的引用。有了这些知识,我们可以编写以下函数来获取与当前会话关联的每个实体类,以及与每个实体关联的每个表名

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);
    }
}
受保护的void testFunc(){
Metamodel Metamodel=entityManager.getMetamodel();
对于(EntityType e:metamodel.getEntities()){
类entityClass=e.getJavaType();
字符串entityTableName=entityClass.getAnnotation(Table.class.name();
System.out.println(“表名称:+entityTableName”);
}
}

但如果entityClass没有表注释,我不能完全确定,因为不明确实体引用的表似乎是个坏主意。无论如何,这是我未经证实的假设。实体获取一个名称,可以作为注释中的参数,也可以从类的名称派生。然后,在编写JPQL查询时,可以将该名称用作表名。因此,在未提供
@table
注释的情况下,这可能就是表的名称。然后,如果
getAnnotation(Table.class)
调用返回null,则可以返回获取实体名称。但是如果entityClass没有表注释,我不能完全确定,因为不明确实体引用的表似乎是个坏主意。无论如何,这是我未经证实的假设。实体获取一个名称,可以作为注释中的参数,也可以从类的名称派生。然后,在编写JPQL查询时,可以将该名称用作表名。因此,在未提供
@table
注释的情况下,这可能就是表的名称。然后,您可以说如果
getAnnotation(Table.class)
调用返回null,然后返回到获取实体的名称。