Spring JPA - 具有多个 JNDI 的单个存储库 class

Spring JPA - Single Repository class with multiple JNDIs

我正在使用 Spring JPA 存储库连接到 Oracle。

我的存储库包是 com.demo.infrastructure.repository; 存储库 class 是 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);
    }
}

我应该有两个 class 这样的不同包(参考 basePackages)。但是我不想要这个解决方案而是想使用单个存储库包和相同的存储库 class.

对我有用的解决方案。

1) 为管理员用户和应用程序用户创建了单独的配置 classes 一个

2) 创建了单独的实体管理器,分别为管理员用户和应用程序用户引用一个

3) 通过 java 代码并使用各自的实体管理器

实例化相同的 Repositoy class(不使用 @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();
}