从 EntityManager 获取所有映射的实体
Posted
技术标签:
【中文标题】从 EntityManager 获取所有映射的实体【英文标题】:Getting all mapped Entities from 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)。
【问题讨论】:
你可以检查这个:: ***.com/questions/43604928/… 【参考方案1】:截至 2016 年(Hibernate 5.2),getAllClassMetadata
和 Configuration
均已弃用。
我想这可以代替:
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。这可能吗? 在这里查看我的答案:***.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;
【讨论】:
以上是关于从 EntityManager 获取所有映射的实体的主要内容,如果未能解决你的问题,请参考以下文章