【问题标题】:Getting all mapped Entities from EntityManager从 EntityManager 获取所有映射的实体
【发布时间】:2011-01-01 16:48:00
【问题描述】:

我有一段维护代码应该在特定时间点向特定用户授予选择权限:

grant select on A_DB.A_TABLE to READ_ONLY_USER;

我想对所有表都这样做。我可以在 Oracle 中使用 select * from tab 或在 MySQL 中使用 show tables 来获取完整列表,然后继续前进。

但由于我手头已经有了 javax.persistence.EntityManager 对象,我想知道是否有其他方法可以获取所有映射的实体,经理知道(我在后台使用 Hibernate)。

【问题讨论】:

标签: java database hibernate data-binding persistence


【解决方案1】:

截至 2016 年(Hibernate 5.2),getAllClassMetadataConfiguration 均已弃用。

我想这可以代替:

Set<EntityType<?>> entities = sessionFactory.getMetamodel().getEntities();

特别是获取类:

List<?> classes = entities.stream()
                          .map(EntityType::getJavaType)
                          .filter(Objects::nonNull)
                          .collect(Collectors.toList());

【讨论】:

  • 从 HIbernate 3 迁移到 5.2.10。我需要从您定义的“实体”到 PersistentClass。这可能吗?
  • 在这里查看我的答案:stackoverflow.com/questions/32780664/…
  • 什么是空检查,我们什么时候从 getJavaType 方法中得到空的 javatypes?
【解决方案2】:

我可以通过两种方式获取所有映射实体及其对应的 SQL 表(可能还有其他方式)。

如果您可以使用 Hibernate 配置对象,最直接的方法是:

    for(Iterator it = config.getClassMappings(); it.hasNext();){
        PersistentClass pc = (PersistentClass) it.next();
        System.out.println(pc.getEntityName() + "\t" + pc.getTable().getName());
    }

或者,您也可以进行更多的转换并从 SessionFactory 中获取相同的信息:

    Map<String, ClassMetadata>  map = (Map<String, ClassMetadata>) sessionFactory.getAllClassMetadata();
    for(String entityName : map.keySet()){
        SessionFactoryImpl sfImpl = (SessionFactoryImpl) sessionFactory;
        String tableName = ((AbstractEntityPersister)sfImpl.getEntityPersister(entityName)).getTableName();
        System.out.println(entityName + "\t" + tableName);
    }

【讨论】:

  • 我无法进入休眠配置,但第二种解决方案有效。
【解决方案3】:

正如 MarcG 的回答所说,getAllClassMetadata() 几年前就被弃用了

截至 Hibernate - 5.4.30.Final - 2021 年 3 月 19 日发布 下面的代码有效,并且不推荐使用

MetamodelImplementor metaModelImpl = (MetamodelImplementor)session.getMetamodel();
Map<String, EntityPersister> entityPersisters = metaModelImpl.entityPersisters();
Collection<EntityPersister> val = entityPersisters.values();               

for (EntityPersister ep : val) {
        AbstractEntityPersister aep = (AbstractEntityPersister)ep;

        System.out.println(aep.getTableName());
        System.out.println(Arrays.toString(aep.getIdentifierColumnNames()));
        for (String propName : aep.getPropertyNames()) {
               System.out.println(propName);
               System.out.println(Arrays.toString(aep.getPropertyColumnNames(propName)));
        }
 }

【讨论】:

    【解决方案4】:

    检查此Map 中的可用内容:

    ((Session) entityManager.getDelegate()).getSessionFactory().getAllClassMetadata() ;
    

    【讨论】:

    • 类元数据实际上仅限于实体本身的属性,不包含任何与映射相关的数据。如果数据库表的名称与实体相同,那就没问题了。
    • 好吧,看起来 getAllClassMetadata 是寻求的解决方案。当然,您的回答更详细。我也许不应该给出提示,而是给出完整的解决方案。不过,我觉得这有问题:)
    【解决方案5】:

    如果你手头有 javax.persistence.EntityManager,下面的方法可以帮你列出所有的表名:

    private List<String> getAllTables() {
        List<String> tableNames = new ArrayList<>();
        Session session = entityManager.unwrap(Session.class);
        SessionFactory sessionFactory = session.getSessionFactory();
        Map<String, ClassMetadata>  map = (Map<String, ClassMetadata>) sessionFactory.getAllClassMetadata();
        for(String entityName : map.keySet()){
            SessionFactoryImpl sfImpl = (SessionFactoryImpl) sessionFactory;
            String tableName = ((AbstractEntityPersister)sfImpl.getEntityPersister(entityName)).getTableName();
            tableNames.add(tableName);
        }
        return tableNames;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 2012-11-03
      • 2012-05-25
      • 2018-09-27
      相关资源
      最近更新 更多