上下文
我想在同一个Spring上下文中使用两个不同的数据库,这些数据库具有共享相同名称但不是相同结构的实体.我依赖Spring Data MongoDB和JPA / JDBC.我有两个包,其中包含以下文件:
> com.bar.entity
> Car.class
> com.bar.repository
> CarRepository.class
> RepoBarMarker.class
> com.bar.config
> MongoConfiguration.class
> com.foo.entity
> Car.class
> com.foo.repository
> CarRepository.class
> RepoFooMarker.class
> com.foo.config
> JPAConfiguration.class
> SpecEntityManagerFactory.class
每个Car.class的内容都不同,我不能重复使用它们. bar使用Spring-Mongo,foo使用Spring-JPA,并通过@EnableMongoRepositories和@EnableJpaRepositories注释初始化存储库.在我的一个应用程序组件中,我尝试访问存储库的foo版本:
@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
看来Spring尝试将bar存储库转换为foo存储库,而不是创建新的bean,就像在同一堆栈中我也有以下异常:
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
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
Spring数据配置
在foo(JPA)包中,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;
}
}
在bar(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,那么一切正常.但是,对于Spring Data存储库来说,是否要避免重命名它们并且每个类型仍然有一个真正的连线,而不是名称(就像这里似乎要做的那样)?