प्रसंग
मैं संस्थाओं का हिस्सा है कि एक ही नाम है कि दो अलग-अलग डेटाबेस एक ही वसंत संदर्भ में उपयोग करना चाहते हैं, लेकिन एक ही संरचना में 2 खजाने इंजेक्षन। मैं स्प्रिंग डेटा मोंगोडीबी और जेपीए/जेडीबीसी पर भरोसा करता हूं। मेरे पास दो पैकेज हैं, जिनमें निम्नलिखित फाइलें हैं:स्प्रिंग डाटा: ही नाम के साथ लेकिन 2 अलग संकुल
- कॉम। बार .entity
- Car.class
- कॉम। बार .repository
- CarRepository.class
- RepoBarMarker.class
- कॉम। बार
- .config MongoConfiguration.class
- कॉम। foo .entity
- Car.class
- कॉम। foo .repository
- CarRepository.class
- RepoFooMarker.class
- कॉम। foo .config
- JPAConfiguration.class
- SpecEntityManagerFactory.class
प्रत्येक Car.class की सामग्री के विभिन्न मैं उन्हें पुन: उपयोग नहीं किया जा सकता है। बार स्प्रिंग-मोंगो और foo स्प्रिंग-जेपीए का उपयोग करता है, और भंडार @EnableMongoRepositories और @EnableJpaRepositories एनोटेशन के माध्यम से शुरू किए जाते हैं।
@Resource
private com.foo.repository.CarRepository carRepository;
मैं निम्नलिखित अपवाद है जब वर्ग @Resource क्षेत्र युक्त बनाई गई है है:
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'carRepository' must be of type [com.foo.repository.CarRepository], but was actually of type [com.sun.proxy.$Proxy31]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:374)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:446)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:420)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:545)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:155)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:305)
... 26 more
अपने आवेदन घटक में से एक में मैं भंडार के foo संस्करण पर पहुँचने का प्रयास करते हैं ऐसा प्रतीत होता है कि वसंत एक बार को भंडार भंडार में एक नया बीन बनाने के बजाय भंडार को बदलने की कोशिश करता है, जैसा कि एक ही स्टैक में है, मेरे पास निम्नलिखित अपवाद भी है:
Caused by: java.lang.IllegalStateException: Cannot convert value of type [com.sun.proxy.$Proxy31 implementing com.bar.repository.CarRepository,org.springframework.data.repository.Repository,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.foo.repository.CarRepository]: no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:93)
at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:64)
... 35 more
अगर मैं भंडार autowire के बजाय का प्रयास करें:
@Autowire
private com.foo.repository.CarRepository carRepository;
मैं निम्न अपवाद प्राप्त करें:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.foo.CarRepository com.shell.ShellApp.carRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.foo.CarRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:509)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:290)
... 26 more
वसंत-डेटा विन्यास
में foo (जेपीए) पैकेज, JPAConfigration.class:
@Configuration
@EnableJpaRepositories(basePackageClasses = RepoFooMarker.class)
public class JPAConfiguration {
@Autowired
public DataSource dataSource;
@Autowired
public EntityManagerFactory entityManagerFactory;
@Bean
public EntityManager entityManager(final EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.createEntityManager();
}
@Bean
public Session session(final EntityManager entityManager)
{
return entityManager.unwrap(Session.class);
}
@Bean
public PlatformTransactionManager transactionManager() throws SQLException {
final JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory);
return txManager;
}
@Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
}
SpecEntityManagerFactory.class:
@Configuration
public class SpecEntityManagerFactory {
@Bean
public EntityManagerFactory entityManagerFactory(final DataSource dataSource) throws SQLException {
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
vendorAdapter.setDatabase(Database.POSTGRESQL);
final LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.foo.entity");
factory.setJpaProperties(getHibernateProperties());
factory.setDataSource(dataSource);
factory.afterPropertiesSet();
return factory.getObject();
}
private Properties getHibernateProperties()
{
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false");
return hibernateProperties;
}
}
बार (MongoDB) पैकेज में, MongoConfiguration.class:
@Configuration
@EnableMongoRepositories(basePackageClasses = RepoBarMarker.class)
public class MongoConfiguration extends AbstractRepoConfig {
@Override
@Bean
public MongoOperations mongoTemplate() {
final MongoClient mongo = this.getMongoClient();
final MongoClientURI mongoUri = this.getMongoClientUri();
final MongoTemplate mongoTemplate = new MongoTemplate(mongo, mongoUri.getDatabase());
mongoTemplate.setReadPreference(ReadPreference.secondaryPreferred());
mongoTemplate.setWriteConcern(WriteConcern.UNACKNOWLEDGED);
return mongoTemplate;
}
}
प्रश्न
यदि मैं foo में इकाई का नाम CarFoo.class और रिपॉजिटरी को CarFooRepository.class में बदलता हूं, तो सब कुछ काम करता है। लेकिन वसंत डेटा भंडारों के लिए, नाम बदलने के बजाए उन्हें फिर से नाम बदलने से बचने के लिए दूर है और अभी भी एक असली तारों का नाम है (जैसा कि ऐसा लगता है)?
क्या आप कृपया अपनी स्प्रिंग डेटा कॉन्फ़िगरेशन दिखा सकते हैं? – geoand
@geoand स्प्रिंग डेटा कॉन्फ़िगरेशन के साथ अपडेट किया गया। मेरा सेटअप अधिक जटिल है, मैंने आवश्यक स्प्रिंग डेटा कॉन्फ़िगरेशन भाग को रखते हुए इसे सरल बना दिया। – Nicolas
मुझे संदेह है कि यह काम करेगा, लेकिन क्या आप 'com.foo.repository.CarRepository' पर' @ रिपोजिटरी ("fooCarRepository") जोड़ने की कोशिश कर रहे हैं? – geoand