2017-04-25 4 views
5

現在、Hibernateのバージョンを最新のバージョン5.2.10にアップグレードしています。 SessionFactoryの作成のために私のコードをHibernateUtilに置き換えました。Hibernateを5.2にアップグレード - セッションファクトリを作成し、エンティティクラスプロパティを取得するためにPersistentClassを置き換えます。

4.3.11.Final(前)

public class HibernateUtil { 
    private HibernateUtil() {} 

    private static SessionFactory sessionFactory; 

    private static Configuration configuration; 

    public static Configuration getConfiguration() { 
     return configuration; 
    } 
    private static SessionFactory buildSessionFactory() { 
     try { 
        if(sessionFactory == null) { 
         configuration = new Configuration(); 
         configuration.configure("hibernate.cfg.xml"); 
         ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() 
           .applySettings(configuration.getProperties()).build(); 
         sessionFactory = configuration 
           .buildSessionFactory(serviceRegistry); 
        } 
      return sessionFactory; 
     } 
     catch (Throwable ex) { 
      throw new ExceptionInInitializerError(ex); 
     } 

    } 
    public static SessionFactory getSessionFactory() { 
     return buildSessionFactory(); 
    } 

    public static Session getSession() { 
     Session hibernateSession = getSessionFactory().getCurrentSession(); 
     return hibernateSession; 
     } 

    public static void shutdown() { 
     getSessionFactory().close(); 
    } 
} 

5.2.10決勝(新):

public class HibernateUtil { 
    private static StandardServiceRegistry registry; 
    private static SessionFactory sessionFactory; 

    public static SessionFactory getSessionFactory() { 
     return buildSessionFactory(); 
    } 

    public static SessionFactory buildSessionFactory() { 
    if (sessionFactory == null) { 
     try { 
     registry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build(); 
     MetadataSources sources = new MetadataSources(registry); 
     Metadata metadata = sources.getMetadataBuilder().build(); 
     sessionFactory = metadata.getSessionFactoryBuilder().build(); 
     } catch (Exception e) { 
     e.printStackTrace(); 
     shutdown(); 
     } 
    } 
    return sessionFactory; 
    } 

public static Session getSession() { 
     Session hibernateSession = getSessionFactory().getCurrentSession(); 
     return hibernateSession; 
     } 

    public static void shutdown() { 
    if (registry != null) { 
     StandardServiceRegistryBuilder.destroy(registry); 
    } 
    } 
} 

今、私は私のリストをフェッチう方法を持っていますDB表名を文字列として渡すことにより、列名を取得します。私は前に4.3.11.Finalでこのようにそれをやった:今

public static List<String> getColumnNames(String tableName) { 

     List<String> columnList=null; 

     Map<String, ClassMetadata> map = HibernateUtil.getSessionFactory().getAllClassMetadata(); 
     Iterator<Entry<String, ClassMetadata>> itr = map.entrySet().iterator(); 

     while(itr.hasNext()){ 

      ClassMetadata classMetaData = itr.next().getValue(); 
      AbstractEntityPersister aep = (AbstractEntityPersister) classMetaData; 

      if(aep.getTableName().split("\\.")[1].equalsIgnoreCase(tableName)){ 

       columnList = new ArrayList<String>(); 
       String[] propertyNames = classMetaData.getPropertyNames(); 

       for(String property : propertyNames){ 
         try { 
          PersistentClass persistentClass = HibernateUtil .getConfiguration().getClassMapping(classMetaData.getEntityName()); 
          String clmName = ((Column) persistentClass.getProperty(property).getColumnIterator().next()).getName(); 
          columnList.add(clmName); 
         } catch(NoSuchElementException e){ 
          log.error("Element not found idenfied as : "+property); 
         } catch(Exception e){ 
          log.error(e.getMessage()); 
         } 
       } 
       break; 
      } 
     } 

     return columnList; 
    } 

アップグレード後には、非推奨の方法getAllClassMetadataを示し、PersistentClassオブジェクトを取得するために困難に直面しています。私は同様の質問hereを見たが、私は正確に解決策を見つけることができませんでした。私の現在のコードのどの部分を、getColumnNames()メソッドが以前と同じように動作するように変更する必要があります。私はその文書を参考にして、代わりにEntityManagerFactory.getMetamodel()を使用すると言いますが、私は同じものの適切な参考例を見つけることができません。これのためにSessionFactory作成メカニズムを変更しなければなりませんか?

答えて

2

最後に、私はVladの記事に感謝しました。私は変更なしでインテグレータコードを取り、私のHibernateUtilgetColumns()メソッドを変更しました。だからここに私のコードです:

SessionFactoryの作成:

public class HibernateUtil { 

    private static final SessionFactory sessionFactory = buildSessionFactory(); 

    public static SessionFactory getSessionFactory() { 
     return buildSessionFactory(); 
    } 

    private static SessionFactory buildSessionFactory() { 
     final BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder().enableAutoClose() 
       .applyIntegrator(MetadataExtractorIntegrator.INSTANCE).build(); 

     final StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder(bootstrapServiceRegistry).configure().build(); 
     return new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory(); 
    } 

    public static Session getSession() { 
     Session hibernateSession = getSessionFactory().getCurrentSession(); 
     return hibernateSession; 
    } 

    public static void shutdown() { 
     getSessionFactory().close(); 
    } 
} 

メタデータの抽出(列名を取得します):あなたの答えを@Vlad

public static List<String> getColumnNames(String tableName) { 

    List<String> columnList = new ArrayList<>(); 

    for (Namespace namespace : MetadataExtractorIntegrator.INSTANCE.getDatabase().getNamespaces()) { 
     for (Table table : namespace.getTables()) { 
      if (table.getName().equalsIgnoreCase(lookupTableName)) { 
       Iterator<Column> iterator = table.getColumnIterator(); 
       while (iterator.hasNext()) { 
        columnList.add(iterator.next().getName()); 
       } 
       break; 
      } 
     } 
     if (!columnList.isEmpty()) 
      break; 
    } 
    return columnList; 
} 
2

大きな質問です。実際、私はそんなに好きで、私がan article about itと書いたのです。

public class MetadataExtractorIntegrator 
    implements org.hibernate.integrator.spi.Integrator { 

    public static final MetadataExtractorIntegrator INSTANCE = 
     new MetadataExtractorIntegrator(); 

    private Database database; 

    @Override 
    public void integrate(
      Metadata metadata, 
      SessionFactoryImplementor sessionFactory, 
      SessionFactoryServiceRegistry serviceRegistry) { 

     database = metadata.getDatabase(); 
    } 

    @Override 
    public void disintegrate(
     SessionFactoryImplementor sessionFactory, 
     SessionFactoryServiceRegistry serviceRegistry) { 

    } 

    public Database getDatabase() { 
     return database; 
    } 
} 

その後、我々はそれを使用するようにHibernateを設定できます。

まず、我々は新しいIntegratorを作成する必要があります。あなたはHibernateのブートストラップメカニズムを使用している場合

、あなたはこのようにそれを追加することができます:あなたはJPAとブートストラップしている場合は、次のよう

final BootstrapServiceRegistryBuilder bsrb = new BootstrapServiceRegistryBuilder(); 
bsrb.enableAutoClose(); 

Integrator integrator = integrator(); 
if (integrator != null) { 
    bsrb.applyIntegrator(integrator); 
} 

final BootstrapServiceRegistry bsr = bsrb.build(); 

final StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder(bsr); 

は、その後、あなたがそれを行うことができます。

protected EntityManagerFactory newEntityManagerFactory() { 
    PersistenceUnitInfo persistenceUnitInfo = persistenceUnitInfo(
     getClass().getSimpleName() 
    ); 

    Map<String, Object> configuration = new HashMap<>(); 


    configuration.put("hibernate.integrator_provider", 
     (IntegratorProvider)() -> Collections.singletonList(MetadataExtractorIntegrator.INSTANCE) 
    ); 

    EntityManagerFactoryBuilderImpl entityManagerFactoryBuilder = new EntityManagerFactoryBuilderImpl(
      new PersistenceUnitInfoDescriptor(persistenceUnitInfo), configuration 
    ); 
    return entityManagerFactoryBuilder.build(); 
} 

さて、次のテスト実行中:

for(Namespace namespace : MetadataExtractorIntegrator.INSTANCE 
    .getDatabase() 
    .getNamespaces()) { 

    for(Table table : namespace.getTables()) { 
     LOGGER.info("Table {} has the following columns: {}", 
      table, 
      StreamSupport.stream(
       Spliterators.spliteratorUnknownSize( 
        table.getColumnIterator(), 
        Spliterator.ORDERED 
       ), 
       false 
      ) 
      .collect(Collectors.toList()) 
     ); 
    } 
} 

Hibernateの出力をすべて現在マップトンログにables:

Table org.hibernate.mapping.Table(post) has the following columns: [ 
    org.hibernate.mapping.Column(id), 
    org.hibernate.mapping.Column(title), 
    org.hibernate.mapping.Column(version) 
] 
Table org.hibernate.mapping.Table(post_comment) has the following columns: [ 
    org.hibernate.mapping.Column(id), 
    org.hibernate.mapping.Column(review), 
    org.hibernate.mapping.Column(version), 
    org.hibernate.mapping.Column(post_id) 
] 
Table org.hibernate.mapping.Table(post_details) has the following columns: [ 
    org.hibernate.mapping.Column(id), 
    org.hibernate.mapping.Column(created_by), 
    org.hibernate.mapping.Column(created_on), 
    org.hibernate.mapping.Column(version) 
] 
Table org.hibernate.mapping.Table(post_tag) has the following columns: [ 
    org.hibernate.mapping.Column(post_id), 
    org.hibernate.mapping.Column(tag_id) 
] 
Table org.hibernate.mapping.Table(tag) has the following columns: [ 
    org.hibernate.mapping.Column(id), 
    org.hibernate.mapping.Column(name), 
    org.hibernate.mapping.Column(version) 
] 

それです!

+0

感謝。上記のHibernateUtilクラスコードを、あなたが提案したHibernateブートストラップメカニズムと置き換えなければなりませんか?また、このメカニズムは比較的新しいものであるため、もう少し説明してください。あなたのコードでhibernate.cfg.xmlがなくても、どのようにコンフィギュレーションを読み込みますか?Line Integratorインテグレータ=インテグレータ()はどのインテグレータメソッドを参照していますか?また、テストメソッドでは、namespace.getTables()はorg.hibernate.boot.relational.Namespaceの一部です。また、列名を取得する方法は? –

+0

[この記事](https://vladmihalcea.com/2017/05/02/how-to-get-access-to-database-table-metadata-with-hibernate-5/)をご覧ください。列にもアクセスできます。 [私の本、High-Performance Java Persistence、GitHubリポジトリ]をフォークできます(https://github.com/vladmihalcea/high-performance-java-persistence/blob/master/core/src/test/java/com/vladmihalcea /book/hpjp/hibernate/metadata/MetadataTest.java)を使用して、ブートストラップと同様に動作するかを確認します。 –

関連する問題