web-dev-qa-db-fra.com

Obtenez le nom de la table à partir du modèle dans Hibernate

Comment puis-je obtenir le nom de la table d'un modèle dans Hibernate?

Apparemment, il existait une méthode getTableName() dans ClassMetadata , mais elle a été supprimée.

Il y a une méthode getClassMapping(String entityName) dans Configuration , mais je ne sais pas comment je peux (ou si je devrais le faire) utiliser Configuration depuis mon implémentation DAO.

Mon implémentation DAO est une sous-classe de HibernateGeneralGenericDao .

UPDATE: Il s'avère que je peux faire ce que j'essaie de faire sans le nom de la table. Cependant, je vais garder la question ouverte (et essayer les réponses au fur et à mesure) pour des raisons de référence.

29
Can Berk Güder

C'est un peu bizarre mais ça marche:

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();
}
34
FoxyBOA

Si vous utilisez l'annotation Table, vous pouvez faire quelque chose comme ceci:

Table table = Entity.class.getAnnotation(Table.class);
String tableName = table.name();
20
Alex Rockwell
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());
2
Kajal

À l'aide de la configuration, vous pouvez appeler la méthode GetClassMapping () pour un type spécifique, ce qui vous donnerait des informations de mappage pour ce type.

(Du moins, c'est le cas dans NHibernate, mais je suppose que cela sera similaire dans Hibernate).

1
Frederik Gheysels

ou en affichant une liste de toutes les colonnes et de toutes les entités de l'interface graphique, j'avais besoin de charger une liste complète de tables, d'entités, d'attributs et de noms de colonnes, types, setters, getters et même de belles étiquettes de manière dynamique. Solution Tom Redfem refactorisée avec le flux Java 8:

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

}

puis la méthode createNewParam est:

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

et deux méthodes d’assistance String pour générer de jolies étiquettes, qui peuvent n’être pas pertinentes pour cet article.

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

Et bien sûr, dans mon WebAppConfig.class, je reçois la fabrique de sessions

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

  return sessionFactory;

}

Peut-être pourrions-nous optimiser un peu plus les flux, mais pour moi, c'était assez rapide et facile.

1
Shilan

Vous pouvez obtenir tous les noms de tables dans votre projet avec cette fonction:

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;
}
0
Anthony Raymond

peut-être utiliser SessionFactory.getClassMetadata ?

0
Michael Pralow