2008-10-02 8 views
8

मेरे पास एक डोमेन-मॉडल के साथ एक एप्लिकेशन ए है जो हाइबरनेट का उपयोग कर डेटाबेस में मैप किया गया है। मेरे पास एक और एप्लीकेशन बी है जो बिल्कुल उसी डोमेन-मॉडल-क्लासेस का उपयोग ए के रूप में करता है और कुछ अतिरिक्त कक्षाएं जोड़ता है।हाइबरनेट के साथ एक डेटाबेस से दूसरे डेटाबेस में डेटा कैसे स्थानांतरित करें?

मेरा लक्ष्य डेटाबेस बी में डेटा ए से डेटा को पढ़ना है और उस डेटा को बी के डेटाबेस में स्थानांतरित करना है (इसकी एक प्रति बनाने के लिए)। इसके अलावा, बी के कुछ डोमेन-वर्गों में ए के डोमेन-क्लासेस (लेकिन बी के डेटाबेस में) के लिए एसोसिएशन (वनटोन) है।

इसे पूरा करने के लिए सबसे अच्छी रणनीति क्या है? मैंने दो सत्र कारखानों के बारे में सोचा और Session.replicate() का उपयोग किया (यह कैसे काम करता है?)। या क्या मुझे ढीले युग्मन के लिए इन दो डोमेन-मॉडल के बीच अतिरिक्त मैपिंग परत बेहतर ढंग से पेश करनी चाहिए?

उत्तर

7

मैंने दो अलग-अलग डेटाबेस प्रकारों (मेरे मामले में डीबी 2 और एमएस एसक्यूएल सर्वर) के बीच डेटा स्थानांतरित करने से पहले यह किया है। मैंने दो अलग-अलग सत्र कारखानों को बनाने के लिए किया था, और उनमें से दोनों को मैपिंग फ़ाइलों की एक ही सूची देना था। तब मैंने बस एक से रिकॉर्ड पढ़े, और उन्हें दूसरे में सहेजा।

बेशक, यह माना जाता है कि दोनों डेटा स्रोत समान थे।

+0

मैं यह कोशिश कर रहा हूं, लेकिन परिपत्र संबंधों के साथ एक समस्या में भाग गया है।डीबी बाधाओं को नष्ट करने की जांच की गई, लेकिन ऐसा करने का एक स्पष्ट तरीका नहीं मिला। अपमानजनक रिश्तों को हटाने/पुनर्निर्माण के लिए कस्टम कोड लिखना पड़ सकता है। –

3

प्रतिलिपि का उद्देश्य क्या है? क्या आपके आवेदन प्रवाह या तर्क का वह हिस्सा है? या सिर्फ सीधे डेटा कॉपी?

यदि यह डेटा कॉपी करने की आवश्यकता के लिए है, तो हाइबरनेट का उपयोग करने की आवश्यकता नहीं है। इसके लिए बहुत सारे उपकरण हैं।

+0

उदाहरण/सिफारिशें कृपया। कुछ भी जो प्रोग्रामेटिक रूप से शुरू किया जा सकता है? –

2

जैसा कि दूसरों ने इंगित किया है, मुझे लगता है कि हमें यह जानना होगा कि आप इसे पूरा करने की कोशिश कर रहे हैं। यदि आप एक बार माइग्रेशन कर रहे हैं, तो ईबेल (निकालें, ट्रांसफॉर्म, लोड) करने के लिए हाइबरनेट से बेहतर उपकरण हैं।

  1. खुला सत्र डेटाबेस ए
  2. की सभी इकाइयां पढ़ें करने के लिए:

    तुम सच में हाइबरनेट (यह आप पर भी लागू होता है, डैनियल) में ऐसा करने पर जोर देते हैं, तो मैं कुछ ऐसा करना चाहते हैं टाइप करें कि आप कॉपी करने की कोशिश कर रहे हैं (सुनिश्चित करें कि आलसी लोडिंग अक्षम है)

  3. डेटाबेस बी के लिए ओपन सत्र बी
  4. इकाइयों को सहेजें या अपडेट करें।

मैं अगर यह आपके आवेदन पत्र (की कार्यक्षमता का हिस्सा है न कि आवेदन एक में या बी

दूसरी ओर से एक अलग उपकरण में ऐसा करना चाहते हैं, जैसे, आवेदन एक है डेटा कंसोल डेटा के लिए, जबकि अनुप्रयोग बी डेटा का उपभोग करता है), आप चीजों को थोड़ा अलग करना चाह सकते हैं। यह जानने के बिना कहना मुश्किल है कि आप वास्तव में क्या खोज रहे हैं।

अंत में, कुछ ऐसा देखने के लिए (मुझे नहीं लगता कि यह वही है जो आप खोज रहे हैं, लेकिन शायद यह आपकी समस्या को अलग तरीके से देखने में आपकी सहायता करेगा) हाइबरनेट शर्ड्स (http://shards.hibernate.org/) है।

2

अन्य टूल्स का प्रयास किया और समस्याएं थीं। मेरा घर लुढ़का हुआ समाधान यहाँ है। कुछ सफाई की जरूरत हो सकती है, लेकिन इसका मांस वहां है।

import java.io.Serializable; 
import java.util.List; 
import java.util.logging.Logger; 

import lombok.Getter; 
import lombok.RequiredArgsConstructor; 
import lombok.Setter; 

import org.hibernate.Session; 
import org.hibernate.Transaction; 

import ca.digitalrapids.lang.GeneralException; 
import ca.digitalrapids.mediamanager.server.dao.hibernate.GenericDAOHibernate; 
import ca.digitalrapids.mediamanager.server.dao.hibernate.GenericDAOHibernate.GenericDAOHibernateFactory; 
import ca.digitalrapids.persist.dao.DAOOptions; 
import ca.digitalrapids.persist.hibernate.HibernateUtil2; 

import com.google.common.collect.ImmutableMultimap; 
import com.google.common.collect.ImmutableSet; 
import com.google.common.collect.Sets; 

@RequiredArgsConstructor 
public class DataMigrator 
{ 
    private static final Logger logger = Logger 
     .getLogger(DataMigrator.class.getName()); 
    private final HibernateUtil2 sourceHibernateUtil2; 
    private final HibernateUtil2 destHibernateUtil2; 
    private final ImmutableSet<Class<?>> beanClassesToMigrate; 
    @Setter @Getter 
    private Integer copyBatchSize = 10; 
    @Setter 
    private GenericDAOHibernateFactory sourceDaoFactory = 
     new GenericDAOHibernate.GenericDAOHibernateFactoryImpl(); 
    @Setter 
    private GenericDAOHibernateFactory destDaoFactory = 
     new GenericDAOHibernate.GenericDAOHibernateFactoryImpl(); 
    private final ImmutableMultimap<Class<?>, Class<?>> entityDependencies; 

    public void run() throws GeneralException 
    { 
     migrateData(sourceHibernateUtil2.getSession(), 
      destHibernateUtil2.getSession()); 
    } 

    private void migrateData(Session sourceSession, Session destSession) 
     throws GeneralException 
    { 
     logger.info("\nMigrating data from old HSQLDB database.\n"); 

     Transaction destTransaction = null; 
     try 
     { 
      destTransaction = destSession.beginTransaction(); 
      migrateBeans(sourceSession, destSession, beanClassesToMigrate, 
       entityDependencies); 
      destTransaction.commit(); 
     } catch (Throwable e) { 
      if (destTransaction != null) 
       destTransaction.rollback(); 
      throw e; 
     } 

     logger.info("\nData migration complete!\n"); 
    } 



    private void migrateBeans(Session sourceSession, Session destSession, 
     ImmutableSet<Class<?>> beanClasses, ImmutableMultimap<Class<?>, Class<?>> deps) 
    { 
     if (beanClasses.isEmpty()) return; 
     Class<?> head = beanClasses.iterator().next(); 
     ImmutableSet<Class<?>> tail = 
      Sets.difference(beanClasses, ImmutableSet.of(head)).immutableCopy(); 
     ImmutableSet<Class<?>> childrenOfHead = getChildren(head, tail, deps); 
     migrateBeans(sourceSession, destSession, childrenOfHead, deps); 
     migrateBean(sourceSession, destSession, head); 
     migrateBeans(sourceSession, destSession, 
      Sets.difference(tail, childrenOfHead).immutableCopy(), deps); 
    } 

    private ImmutableSet<Class<?>> getChildren(Class<?> parent, 
     ImmutableSet<Class<?>> possibleChildren, 
     ImmutableMultimap<Class<?>, Class<?>> deps) 
    { 
     ImmutableSet<Class<?>> parentDeps = ImmutableSet.copyOf(deps.get(parent)); 
     return Sets.intersection(possibleChildren, parentDeps).immutableCopy(); 
    } 

    private void migrateBean(Session sourceSession, Session destSession, 
     Class<?> beanClass) 
    { 
     GenericDAOHibernate<?, Serializable> sourceDao = 
      sourceDaoFactory.get(beanClass, sourceSession); 
     logger.info("Migrating "+sourceDao.countAll()+" of "+beanClass); 

     DAOOptions options = new DAOOptions(); 
     options.setMaxResults(copyBatchSize); 
     List<?> sourceBeans; 
     int firstResult = 0; 
     int sourceBeansSize; 
     do { 
      options.setFirstResult(firstResult); 
      sourceBeans = sourceDao.findAll(options); 
      sourceBeansSize = sourceBeans.size(); 
      @SuppressWarnings("unchecked") 
      GenericDAOHibernate<Object, Serializable> destDao = 
       (GenericDAOHibernate<Object, Serializable>) 
       destDaoFactory.get(beanClass, destSession); 
      for (Object sourceBean : sourceBeans) 
      { 
       destDao.save(sourceBean); 
      } 
      firstResult += copyBatchSize; 
      sourceSession.clear();/* prevent memory problems */ 
     } while (sourceBeansSize >= copyBatchSize); 
    } 
} 
+2

आयात ca.digitalrapids.lang.GeneralException क्या आयात है? इसे कहीं भी नहीं मिला – john

+0

@john https://en.wikipedia.org/wiki/Digital_Rapids_Corporation - क्या यह संभव है कि यह कुछ मालिकाना पुस्तकालय है? (मुझे उम्मीद नहीं है, अगर यह उन पुस्तकालयों पर निर्भर करता है जो सार्वजनिक रूप से उपलब्ध नहीं हैं तो इसका उत्तर बहुत कम उपयोगी लगता है)। – EJoshuaS

+0

@EJoshuaS मुझे लगता है कि यह है। मेरी सोच है: इस जवाब को दो अपवॉट मिले। इसका मतलब है कि कम से कम दो लोग जानते हैं कि वे पुस्तकालय क्या हैं और हमारे साथ उन पुस्तकालयों के लिंक साझा कर सकते हैं – john

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