是否可以确定实体的本机表名称?
如果存在Table
注释,则很容易:
entityClass.getAnnotation(Table.class).name()
但如果没有Table
注释,那该怎么办?
Hibernate通过Configuration
类提供此信息:
configuration.getClassMapping(entityClass.getSimpleName()).getTable().getName()
JPA中有类似内容吗?
答案 0 :(得分:12)
这是我使用EclipseLink(没有映射文件)的方法:
/**
* Returns the table name for a given entity type in the {@link EntityManager}.
* @param em
* @param entityClass
* @return
*/
public static <T> String getTableName(EntityManager em, Class<T> entityClass) {
/*
* Check if the specified class is present in the metamodel.
* Throws IllegalArgumentException if not.
*/
Metamodel meta = em.getMetamodel();
EntityType<T> entityType = meta.entity(entityClass);
//Check whether @Table annotation is present on the class.
Table t = entityClass.getAnnotation(Table.class);
String tableName = (t == null)
? entityType.getName().toUpperCase()
: t.name();
return tableName;
}
答案 1 :(得分:3)
如果没有表注释(并且没有ORM.xml),那么在JPA中,表名是根据类名形成的(参见JPA规范)。那么为什么你需要一个存取方法?
请参阅http://www.datanucleus.org/products/accessplatform_2_0/jpa/orm/datastore_identifiers.html
答案 2 :(得分:2)
我的一位同事发现了由 Hibernate 支持的 Spring Data JPA 环境的以下解决方案:
import org.hibernate.internal.SessionImpl;
import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
@Service
public class EntityClassToTableNameMapper {
@Transactional
public String[] getTableNames(EntityManager em, Class entityClass) {
Object entityExample;
try {
entityExample = entityClass.newInstance();
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
SessionImpl session = em.unwrap(SessionImpl.class);
EntityPersister persister = session.getEntityPersister(null, entityExample);
if (persister instanceof AbstractEntityPersister) {
AbstractEntityPersister persisterImpl = (AbstractEntityPersister) persister;
String tableName = persisterImpl.getTableName();
String rootTableName = persisterImpl.getRootTableName();
return new String[] {rootTableName, tableName};
} else {
throw new RuntimeException("Unexpected persister type; a subtype of AbstractEntityPersister expected.");
}
}
}
答案 3 :(得分:1)
如果您使用@Table注释,则没有问题,如您所示。如果您不使用该注释,则表名与类名相同(JPA默认值)。
如果您使用映射文件,您需要解析它并重新检索表名,这很有趣 - 这不是很困难,但需要一些工作。如果您害怕性能问题,那么您可以解析映射文件一次并缓存所有表名。
答案 4 :(得分:0)
询问底层ORM的元模型是最可靠的:查看@Table的存在是不够的,不仅可以通过XML配置(例如orm.xml)覆盖它,而且使用JOINED策略, @Table可能是一个超级班。