2017-04-25 5 views
5

मैं वर्तमान में अपने हाइबरनेट संस्करण को नवीनतम संस्करण 5.2.10 में अपग्रेड कर रहा हूं। मैंने सत्र कोड फैक्टरी के लिए HibernateUtil में अपना कोड बदल दिया।हाइबरनेट 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); 
    } 
    } 
} 

अब मैं एक तरीका है जिसके मुझे सूची प्राप्त होता है एक स्ट्रिंग के रूप में डीबी टेबल नाम पास करके कॉलम नामों का। मैं 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() का उपयोग करने के लिए कहता है लेकिन मुझे इसके उपयुक्त संदर्भ उदाहरण नहीं मिल रहे हैं। इसके लिए मुझे सत्र फैक्ट्री निर्माण तंत्र भी बदलना होगा?

उत्तर

2

ठीक है आखिरकार मैंने इसे व्लाल्ड के लेख का धन्यवाद दिया। मैंने बिना किसी बदलाव के इंटीग्रेटर कोड लिया और मेरे HibernateUtil और getColumns() विधि को संशोधित किया।

SessionFactory निर्माण: तो यहाँ मेरी कोड है आपके उत्तर के लिए

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 लिखा था।

सबसे पहले, हम एक नया Integrator बनाने की जरूरत:

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

फिर, हम सिर्फ हाइबरनेट कॉन्फ़िगर इसका इस्तेमाल कर सकते हैं।

आप हाइबरनेट बूटस्ट्रैप तंत्र का उपयोग कर रहे हैं, तो आप इसे इस तरह जोड़ सकते हैं:

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

आप जेपीए साथ bootstrapping रहे हैं, तो आप यह कर सकते इस प्रकार है:

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

हाइबरनेट आउटपुट सभी अभी मैप टी लॉग में 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

धन्यवाद @Vlad:

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

मेटाडाटा इक्स्त्रैक्टर (कॉलम नाम प्राप्त करें)।तो क्या मुझे अपने हाइबरनेट को क्लास कोड को प्रतिस्थापित करना होगा जिसे मैंने उपरोक्त वर्णित हाइबरनेट बूटस्ट्रैप तंत्र के साथ बताया है? इसके अलावा आप इसके बारे में कुछ और बता सकते हैं क्योंकि यह तंत्र मेरे लिए अपेक्षाकृत नया है। यह कॉन्फ़िगरेशन को आपके कोड में der's no hibernate.cfg.xml के रूप में कैसे पढ़ता है। लाइन इंटीग्रेटर इंटीग्रेटर = इंटीग्रेटर() किस इंटीग्रेटर विधि को संदर्भित करता है? परीक्षण विधि में, namepace.getTables(), यह org.hibernate.boot.relational.Namespace का हिस्सा है। मैं कॉलम नाम कैसे प्राप्त कर सकता हूं? –

+0

यह देखने के लिए [इस आलेख] (https://vladmihalcea.com/2017/05/02/how-to-get-access-to-डेटा-table-metadata-with-hibernate-5/) देखें कि आप देख सकते हैं कॉलम तक पहुंच प्राप्त करें। आप कांटा [मेरी पुस्तक, उच्च प्रदर्शन जावा दृढ़ता, गिटहब भंडार] कर सकते हैं (https://github.com/vladmihalcea/high-performance-java-persistence/blob/master/core/src/test/java/com/vladmihalcea /book/hpjp/hibernate/metadata/MetadataTest.java) यह देखने के लिए कि यह कैसे काम करता है, साथ ही साथ बूटस्ट्रैप भी। –

संबंधित मुद्दे