Reputation: 113300
How do I get the table name for a model in Hibernate?
Apparently there used to be a getTableName()
method in ClassMetadata
, but it's been removed.
There's a getClassMapping(String entityName)
method in Configuration
, but I don't know how I can (or if I should) use Configuration from within my DAO implementation.
My DAO implementation is a subclass of HibernateGeneralGenericDao.
UPDATE: It turns out I can do what I'm trying to do without the table name. However, I will keep the question open (and try the answers as they come) for the sake of reference.
Upvotes: 41
Views: 53899
Reputation: 461
As in Hibernate 6 the mentioned solutions did not work for me I ended up with the following implementation:
private String getTableName(final Class<?> cls) {
final var sessionFactory = entityManager.getEntityManagerFactory().unwrap(SessionFactoryImplementor.class);
final var metaModel = sessionFactory.getRuntimeMetamodels().getMappingMetamodel();
return metaModel.getEntityDescriptor(cls).getMappedTableDetails().getTableName();
}
Upvotes: 2
Reputation: 362
classMetadata
is deprecated.
Use:
@PersistenceContext
private EntityManager entityManager;
public String extractTableName(final Class<?> modelClazz) {
final MetamodelImpl metamodel = (MetamodelImpl) entityManager.getMetamodel();
final EntityPersister entityPersister = metamodel.entityPersister(modelClazz);
if (entityPersister instanceof SingleTableEntityPersister) {
return ((SingleTableEntityPersister) entityPersister).getTableName();
} else {
throw new IllegalArgumentException(modelClazz + " does not map to a single table.");
}
}
Upvotes: 4
Reputation: 99
Since getClassMetadata method is deprecated. Try something like this.
Configuration configuration = new Configuration();
configuration.configure();
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure().build();
Metadata = new MetadataSources(standardRegistry).getMetadataBuilder().build();
SessionFactory sessionFactory = configuration.buildSessionFactory();
String tableName=Metadata.getEntityBinding(entityName).getQualifiedTableName().toString();
Upvotes: 0
Reputation: 833
or displaying a list of all columns and all entities in the GUI, I needed to load a full list of table, entity, attributes and column names, types, setters, getters and even nice labels dynamically and that's how I did it based on @Tom Redfem solution refactored with java 8 stream:
public void loadHibernateMetadata() throws ClassNotFoundException {
Map<String, ClassMetadata> hibernateMetadata = sessionFactory.getAllClassMetadata();
hibernateMetadata.values()
.stream()
.filter(metadata -> metadata != null && metadata instanceof AbstractEntityPersister)
.map(AbstractEntityPersister.class::cast)
.forEach( persister -> createNewnParam(persister));
;
}
and then createNewParam method is:
private void createNewParam(AbstractEntityPersister persister) {
try {
Class<?> $class = Class.forName(persister.getEntityName());
List<String> getterNameRoster = Lists.newArrayList($class.getMethods())
.stream()
.filter( method -> method.getName().startsWith("get") || method.getName().startsWith("is"))
.map(getterName -> getterName.getName())
.collect(toList())
;
List<String> setterNameRoster = Lists.newArrayList($class.getMethods())
.stream()
.filter( method -> method.getName().startsWith("set") )
.map(setterName -> setterName.getName())
.collect(toList())
;
Iterable<AttributeDefinition> attrs = persister.getAttributes();
attrs.forEach(a -> {
String columnName = persister.getPropertyColumnNames(a.getName())[0];
org.hibernate.type.Type hibernateType =persister.getPropertyType(a.getName());
Optional<String> optionalGetter = getterNameRoster.stream()
.filter(getterStr -> getterStr.equalsIgnoreCase( String.format("get%s", a.getName()) ) ||
getterStr.equalsIgnoreCase( String.format("is%s", a.getName())) )
.findFirst()
;
String getterName = optionalGetter.isPresent() ? optionalGetter.get() : new String("");
Optional<String> optionalSetter = setterNameRoster.stream()
.filter(setterStr -> setterStr.equalsIgnoreCase( String.format("set%s", a.getName()) ))
.findFirst()
;
String setterName = optionalSetter.isPresent() ? optionalSetter.get() : new String("");
Param param = new Param(persister.getEntityName(),
persister.getTableName().replaceAll("\"", "").toUpperCase(),
columnName.replaceAll("\"", "").toUpperCase(),
a.getName(),
getterName,
setterName,
hibernateType.getName(),
capitalizeFirstLetter(splitCamelCase(a.getName()))
);
hibernateParamList.add(param);
logger.debug(param.toString());
});
} catch (ClassNotFoundException e) {
logger.error(String.format("error occured generating the params %s" , e));
}
}
and two String helper method to generate nice labels, which can be irrelevant to this post
private String splitCamelCase(String s) {
return s.replaceAll(
String.format("%s|%s|%s",
"(?<=[A-Z])(?=[A-Z][a-z])",
"(?<=[^A-Z])(?=[A-Z])",
"(?<=[A-Za-z])(?=[^A-Za-z])"
),
" "
);
}
private String capitalizeFirstLetter(String s) {
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
And of course in my WebAppConfig.class I get the session factory
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder =
new LocalSessionFactoryBuilder(dataSource());
builder.addProperties(hibernateProperties());
builder.scanPackages(new String[] { "com....model" });
SessionFactory sessionFactory = builder.buildSessionFactory();
return sessionFactory;
}
Maybe we can optimize streams a little bit more, but for me it was quite fast and easy.
Upvotes: 1
Reputation: 7862
You can get every tables name in your project with this function :
public Set<String> getTablesName() {
Set<String> names = new HashSet<>();
SessionFactory sessionFactory = emf.unwrap(SessionFactory.class);
Map<String, ClassMetadata> classMetadataMap = sessionFactory.getAllClassMetadata();
for (ClassMetadata classMetadata : classMetadataMap.values()) {
AbstractEntityPersister aep = (AbstractEntityPersister) classMetadata;
String tableName = aep.getTableName();
if (StringUtils.isBlank(tableName) || StringUtils.containsWhitespace(tableName)) {
continue;
}
names.add(tableName);
}
return names;
}
Upvotes: 0
Reputation: 5836
It's a bit weird but it works:
ClassMetadata hibernateMetadata = sessionFactory.getClassMetadata(pClassName);
if (hibernateMetadata == null)
{
return;
}
if (hibernateMetadata instanceof AbstractEntityPersister)
{
AbstractEntityPersister persister = (AbstractEntityPersister) hibernateMetadata;
String tableName = persister.getTableName();
String[] columnNames = persister.getKeyColumnNames();
}
Upvotes: 37
Reputation:
Configuration cfg = new Configuration().configure();
cfg.addResource("com/struts/Entities/User.hbm.xml");
cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
Mappings m=cfg.createMappings();
System.out.println(">> class: "+m.getClass(className));
System.out.println("User table name:: "+m.getClass("User").getTable().getName());
Upvotes: 2
Reputation: 1474
If you're using the Table annotation you could do something like this:
Table table = Entity.class.getAnnotation(Table.class);
String tableName = table.name();
Upvotes: 32
Reputation: 56934
Using the Configuration, you can call the GetClassMapping() method for a specific type, which would give you some mapping information for that type.
(At least, this is the case in NHibernate, but I suppose that this will be similar in Hibernate).
Upvotes: 1