How to retrieve mapping table name for an entity in JPA at runtime?

If no table annotation is present (and no ORM.xml) then in JPA the table name is formed based on the class name (see the JPA spec). Hence why exactly do you need an accessor method ?

See http://www.datanucleus.org/products/accessplatform_2_0/jpa/orm/datastore_identifiers.html


A colleague of mine found the following solution for a Spring Data JPA environment backed by Hibernate:

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.");
        }
    }
}

This is the method I am using with EclipseLink (no mapping file):

/**
 * 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;
}

Tags:

Java

Jpa

Entity