我使用Spring JPA Repository连接到Oracle。
我的Repository包是com.demo.infrastructure.repository;Repository类是StoreRepo.java。
@Repository
public interface StoreRepo extends JpaRepository<StoreAttribute, String> {
@Query("select storeAttributeName from StoreAttribute order by storeAttributeName asc")
List<String> fetchAllStoreAttributeNames();
List<StoreAttribute> findAllByOrderByStoreAttributeNameAsc();
}
问题:我正在使用JNDI配置来配置数据源,目前只有一个JNDI条目。目前它只有一个JNDI条目。现在我想对同一个数据库使用两个用户名,一个是管理员(读写)访问,另一个是用户(只读)访问。这两个用户将访问同一个仓库和同一个实体。
我尝试了现有的解决方案,即为每个数据源使用两个不同的存储库包。但我希望Repository "StoreRepo "是相同的。
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryAdmin",
basePackages = { "com.demo.infrastructure.repository" }
)
public class DataSourceAdminConfig {
@Primary
@Bean(name = "dataSourceAdmin")
public DataSource dataSource() {
return new JndiDataSourceLookup().getDataSource("jdbc/myds_admin");
}
@Primary
@Bean(name = "entityManagerFactoryAdmin")
public LocalContainerEntityManagerFactoryBean
entityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("dataSourceAdmin") DataSource dataSource
) {
return builder.dataSource(dataSource).
packages("com.demo.domain.model.entities").
persistenceUnit("read-write").
build();
}
@Primary
@Bean(name = "transactionManagerAdmin")
public PlatformTransactionManager transactionManager(
@Qualifier("entityManagerFactoryAdmin") EntityManagerFactory
entityManagerFactory
) {
return new JpaTransactionManager(entityManagerFactory);
}
}
我应该有两个这样的类,用不同的包(参考basePackages)。但我不希望这种解决方案,而是希望使用单一的存储库包和相同的存储库类。
对我来说有效的解决方案。
1) 创建单独的配置类,管理员用户和应用程序用户各一个。
2)创建了sepate实体管理参考,管理员用户和应用程序用户各一个。
3) 通过java代码和使用各自的实体管理器实例化同一个Repositoy类(不使用@Repository注解)。
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryAdmin"
)
public class AdminUserConfig {
@Primary
@Bean(name = "dataSourceAdmin")
public DataSource dataSourceAdmin(@Value("${spring.datasource.admin-user.jndi-name}") String key) {
return new JndiDataSourceLookup().getDataSource(key);
}
@Primary
@Bean(name = "entityManagerFactoryAdmin")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryAdmin(
EntityManagerFactoryBuilder builder,
@Qualifier("dataSourceAdmin") DataSource dataSource
) {
return builder.dataSource(dataSource).
packages("com.demo.domain.model.entities").
persistenceUnit("read-write").
build();
}
@Bean(name = "entityManagerAdmin")
public EntityManager entityManagerAdmin(@Qualifier("entityManagerFactoryAdmin") EntityManagerFactory
entityManagerFactory) {
return SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory);
}
@Bean(name = "adminRepository")
public StoreRepo readWriteDimStoreRepository(@Qualifier("jpaRepositoryFactoryAdmin")
JpaRepositoryFactory repositoryFactory) {
return repositoryFactory.getRepository(StoreRepo.class);
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryApp"
)
public class AppUserConfig {
@Primary
@Bean(name = "dataSourceApp")
public DataSource dataSourceApp(@Value("${spring.datasource.App-user.jndi-name}") String key) {
return new JndiDataSourceLookup().getDataSource(key);
}
@Primary
@Bean(name = "entityManagerFactoryApp")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryApp(
EntityManagerFactoryBuilder builder,
@Qualifier("dataSourceApp") DataSource dataSource
) {
return builder.dataSource(dataSource).
packages("com.demo.domain.model.entities").
persistenceUnit("read-only").
build();
}
@Bean(name = "entityManagerAdmin")
public EntityManager entityManagerApp(@Qualifier("entityManagerFactoryApp") EntityManagerFactory
entityManagerFactory) {
return SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory);
}
@Bean(name = "AppRepository")
public StoreRepo readOnlyStoreRepository(@Qualifier("jpaRepositoryFactoryApp")
JpaRepositoryFactory repositoryFactory) {
return repositoryFactory.getRepository(StoreRepo.class);
}
}
//@Repository
public interface StoreRepo extends JpaRepository<StoreAttribute, String> {
@Query("select storeAttributeName from StoreAttribute order by
storeAttributeName asc")
List<String> fetchAllStoreAttributeNames();
List<StoreAttribute> findAllByOrderByStoreAttributeNameAsc();
}