मैंने इसे 'न्यूनतम' एकाधिक डेटासोर्स प्रोजेक्ट बनाया है ताकि यह काम करने में मेरी सहायता कर सके। वहां 7 जावा कक्षाएं और अन्य कॉन्फ़िगरेशन हैं, इसलिए मैं केवल इस जवाब में महत्वपूर्ण निष्कर्ष पोस्ट करूंगा। आप GitHub से पूर्ण परियोजना प्राप्त कर सकते हैं: इन के साथ
@Entity public class Foo { /* Constructors, fields and accessors/mutators */ }
@Entity public class Bar { /* Constructors, fields and accessors/mutators */ }
एसोसिएटेड हम दो खजाने पैदा करेगा: https://github.com/gratiartis/multids-demo
डेमो दो जेपीए संस्थाओं सेट करता है।
public interface FooRepository extends JpaRepository<Foo, Long> {}
public interface BarRepository extends JpaRepository<Bar, Long> {}
अब हम अपने स्वयं के डेटाबेस में एक मेज पर है कि इन नक्शों से प्रत्येक सुनिश्चित करने की आवश्यकता: स्प्रिंग डाटा के awesomeness के लिए धन्यवाद, हम अपने आप को कुछ बहुत पूर्ण विशेषताओं खजाने विशुद्ध रूप से इंटरफेस जो JpaRepository विस्तार को परिभाषित करते हुए प्राप्त कर सकते हैं ।
इसे प्राप्त करने के लिए, हमें दो अलग-अलग इकाई प्रबंधकों की आवश्यकता होगी, जिनमें से प्रत्येक का अलग डेटा स्रोत होगा। हालांकि, स्प्रिंग जावा कॉन्फ़िगरेशन @Configuration
कक्षा में, हमारे पास केवल @EnableJpaRepositories
एनोटेशन हो सकता है और प्रत्येक ऐसी एनोटेशन केवल एक EntityManagerFactory का संदर्भ दे सकती है। इसे प्राप्त करने के लिए, हम दो अलग @Configuration
कक्षाएं बनाते हैं: FooConfig और BarConfig।
@Bean(name = "fooDataSource")
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setName("foodb").setType(EmbeddedDatabaseType.HSQL).build();
}
@Bean(name = "barDataSource")
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setName("bardb").setType(EmbeddedDatabaseType.HSQL).build();
}
@Bean(name = "barEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lef =
new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource());
lef.setJpaVendorAdapter(jpaVendorAdapter);
lef.setPackagesToScan("com.sctrcd.multidsdemo.domain.bar");
lef.setPersistenceUnitName("barPersistenceUnit");
lef.afterPropertiesSet();
return lef.getObject();
}
@Bean(name = "fooEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lef =
new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource());
lef.setJpaVendorAdapter(jpaVendorAdapter);
lef.setPackagesToScan("com.sctrcd.multidsdemo.domain.foo");
lef.setPersistenceUnitName("fooPersistenceUnit");
lef.afterPropertiesSet();
return lef.getObject();
}
प्रत्येक विन्यास एक EntityManagerFactory के रूप में ऊपर परिभाषित करना चाहिए, अपने स्वयं के डेटा स्रोत() @Bean विधि का संदर्भ जो:
इन @Configuration वर्गों में से प्रत्येक एक डेटास्रोत एक एम्बेडेड HSQL डेटाबेस के आधार पर परिभाषित करेगा। यह @Entity बीन्स के पथ को भी परिभाषित करता है जो इसे प्रबंधित करता है। आपको यह सुनिश्चित करने की ज़रूरत है कि विभिन्न डेटा स्रोतों के लिए @ एंटीटी बीन्स अलग-अलग पैकेजों में हैं।
इस बिंदु पर यह ध्यान देने योग्य है कि यदि इनमें से प्रत्येक कॉन्फ़िगरेशन कुंजी दृढ़ता सेम (यानी इकाई प्रबंधक फ़ैक्टरी) के लिए डिफ़ॉल्ट नामों का उपयोग करता है, तो वसंत देखेंगे कि EntityManager इंटरफ़ेस के साथ दो बीन्स हैं, जिनमें से दोनों का एक ही नाम है । तो एक चुना जाएगा। https://github.com/gratiartis/multids-demo/tree/1-unnamed-entitymanager-beans
इसका कारण यह है कि उदाहरण में, स्प्रिंग "foodb से संबंधित सेम को तार किया है:
Not an managed type: class com.sctrcd.multidsdemo.domain.bar.Bar
इस डेमो परियोजना यहां की शाखा में देखा जा सकता: यह इस तरह के रूप त्रुटियां होती हैं "डेटाबेस, और बार उस डेटाबेस में एक इकाई नहीं है। दुर्भाग्यवश बैर रिपोजिटरी को फू इकाई प्रबंधक के साथ रखा गया है।
हम कॉन्फ़िगरेशन क्लास में हमारे सभी बीन्स नामकरण करके इस समस्या को हल करते हैं। यानी
@Bean(name = "fooDataSource") public DataSource dataSource() { .. }
@Bean(name = "fooEntityManager") public EntityManager entityManager() { .. }
इस बिंदु पर यदि आप इस परियोजना में परीक्षण चलाने के लिए थे, तो आप इस तरह के रूप में चेतावनी देख सकते हैं:
No bean named 'entityManagerFactory' is defined.
इसका कारण यह है ... drumroll ... हमारे पास नहीं है डिफ़ॉल्ट नाम "entityManagerFactory" के साथ एक EntityManagerFactory। हमारे पास "fooEntityManagerFactory" नामक एक है और दूसरा "barEntityManagerFactory" कहा जाता है। वसंत एक डिफ़ॉल्ट नाम के साथ कुछ ढूंढ रहा है, इसलिए हमें इसे चीजों को अलग-अलग तारों के साथ निर्देशित करने की आवश्यकता है।
जैसा कि यह पता चला है, यह करने के लिए अविश्वसनीय रूप से सरल है। हमें प्रत्येक @ कॉन्फ़िगरेशन कक्षा के लिए @EnableJpaRepositories एनोटेशन में सही संदर्भ डालने की आवश्यकता है।
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "fooEntityManagerFactory",
transactionManagerRef = "fooTransactionManager",
basePackages = {"com.sctrcd.multidsdemo.integration.repositories.foo"})
public class FooConfig {
// ...
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "barEntityManagerFactory",
transactionManagerRef = "barTransactionManager",
basePackages = { "com.sctrcd.multidsdemo.integration.repositories.bar" })
public class BarConfig {
// ...
}
आप देख सकते हैं, इन @EnableJpaRepositories एनोटेशन में से प्रत्येक के लिए एक विशिष्ट EntityManagerFactory और PlatformTransactionManager नामित परिभाषित करता है। वे यह भी निर्दिष्ट करते हैं कि उन बीन्स के साथ कौन से भंडारों को तारित किया जाना चाहिए। उदाहरण में, मैंने डेटाबेस-विशिष्ट संकुल में भंडार रखे हैं। एनोटेशन में फ़िल्टर को शामिल करके, प्रत्येक व्यक्तिगत भंडार को नाम से परिभाषित करना भी संभव है, लेकिन डेटाबेस द्वारा रिपॉजिटरीज को अलग करके, मेरा मानना है कि चीजों को और अधिक पठनीय करना चाहिए।
इस बिंदु पर आपको दो अलग-अलग डेटाबेस में इकाइयों का प्रबंधन करने के लिए स्प्रिंग डेटा रिपॉजिटरीज़ का उपयोग करके एक कार्यरत आवेदन होना चाहिए। उपरोक्त लिंक से परियोजना को पकड़ने के लिए स्वतंत्र महसूस करें और यह देखने के लिए परीक्षण चलाएं। उम्मीद है कि यह उत्तर अधिक लोगों के लिए उपयोगी है, क्योंकि मैंने जितना संभव हो सके उतना आसान कोड करने के लिए काम करने के लिए एक सभ्य समय बिताया है जितना मैं प्रबंधित कर सकता हूं। उत्तर या डेमो परियोजना के सुधार के लिए कोई विचार स्वागत है।