2009-03-11 25 views
26

¿Cómo obtengo el nombre de la tabla para un modelo en Hibernate?Obtener el nombre de la tabla del modelo en Hibernate

Aparentemente solía haber un método getTableName() en ClassMetadata, pero se ha eliminado.

Hay un método getClassMapping(String entityName) en Configuration, pero no sé cómo puedo (o si debería) usar Configuration desde mi implementación DAO.

Mi implementación DAO es una subclase de HibernateGeneralGenericDao.

ACTUALIZACIÓN: Resulta que yo puedo hacer lo que yo estoy tratando de hacer sin el nombre de la tabla. Sin embargo, voy a mantener la pregunta abierta (y probar las respuestas tal como vienen) por el bien de referencia.

Respuesta

17

Si está utilizando la anotación tabla se podría hacer algo como esto:

Table table = Entity.class.getAnnotation(Table.class); 
String tableName = table.name(); 
+0

No soy (y, sinceramente, acabo de enterarme de las anotaciones), pero esta es una buena idea. Gracias. –

+9

Bastante seguro de que esto solo funciona si configura la anotación de la tabla en cada entidad.Hibernate funciona perfectamente bien si no lo hace (deriva el nombre del nombre de la entidad) – Justin

1

Uso de la configuración, puede llamar al método GetClassMapping() para un tipo específico, lo que le daría un poco de información de mapeo para ese tipo.

(Al menos, este es el caso en NHibernate, pero supongo que esto será similar en Hibernate).

+0

Sí, pero ¿cómo uso la configuración? ¿Puedo simplemente crear una nueva instancia? –

+0

Algunas opciones son crear una nueva instancia como durante la inicialización; mantenerlo como estático o singleton; o usa la reflexión para tomarla de SessionFactory. Una vez que tenga la configuración: configuration.getClassMapping ("foo"). GetTable(). GetName(); –

32

Es un poco extraño, pero funciona:

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(); 
} 
+1

Hay un paréntesis adicional cerca del final de la quinta línea. Alguien con suficiente reputación debería arreglarlo. Además, vea y piense en https://meta.stackoverflow.com/questions/251580/what-is-the-reason-behind-the-6-character-minimum-for-suggested-edits y https: // meta. stackoverflow.com/questions/277184/why-is-it-necessary-for-me-to-write-6-character-if-just-one-is-missing-and-what –

2
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()); 
0

, usted puede obtener todos los nombres de las tablas en su proyecto con esta función:

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; 
} 
1

o mostrar una lista de todas las columnas y todas las entidades en la GUI, necesitaba cargar dinámicamente una lista completa de tabla, entidad, atributos y nombres de columnas, tipos, setters, getters e incluso etiquetas agradables y así lo hice basado en el refactor de solución @Tom Redfem ed con java 8 corriente:

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)); 
     ; 

} 

y luego método createNewParam es:

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

y el método de dos cuerdas ayudante para generar etiquetas agradables, que puede ser irrelevante para este 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); 
} 

Y por supuesto en mi WebAppConfig.class obtengo la fábrica de sesiones

public SessionFactory sessionFactory() { 
    LocalSessionFactoryBuilder builder = 
      new LocalSessionFactoryBuilder(dataSource()); 
    builder.addProperties(hibernateProperties()); 
    builder.scanPackages(new String[] { "com....model" }); 
    SessionFactory sessionFactory = builder.buildSessionFactory(); 

    return sessionFactory; 

}

Tal vez podamos optimizar las transmisiones un poco más, pero para mí fue bastante rápido y fácil.

Cuestiones relacionadas