spring - Spring JPA - 具有多个 JNDI 的单个存储库类
问题描述
我正在使用 Spring JPA Repository 连接到 Oracle。
我的存储库包是 com.demo.infrastructure.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 条目。现在我想为同一个数据库使用两个用户名,一个具有管理员(读写)访问权限,另一个具有用户(只读)访问权限。这两个用户都将访问相同的存储库和相同的实体。
我尝试了现有的解决方案,它为每个数据源使用两个不同的存储库包。但我希望存储库“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)为管理员用户和应用程序用户创建了单独的实体管理器引用
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();
}
推荐阅读
- swiftui - 如何在 SwiftUI 中使用带有 ObservedObject 的 Picker?
- python - Python script runs flawless when executed in shell, but throws unicode errors when executed as systemd service
- macos - How do I prevent an application from being used as a default opener for ANY file?
- python - 如何在python中降低这个嵌套循环代码的时间复杂度
- r - How do I turn a string of words into an edgelist?
- observable - observe changes in a different viewmodel
- google-apps-script - Unable to set freeze row in spreadsheet
- linux - 如果文件不存在,则毫无例外地从 GCS 中删除
- c++ - IloBoolVarArray syntax help needed
- angular - Is there a way to automatically get to the bottom of a virtual scroll?