java无法访问类org的成员。springframework。数据jpa。util。带修改器的HibernateProxyDetector
我正在我们的项目(SpringMVC和hibernate)中通过以下方式实现多租户特性this tutorial 但它不起作用
其概念是当应用程序初始化时,从主数据库获取租户详细信息,如url、用户名和密码,并使用它创建租户数据源。当应用程序运行时,会出现以下错误
错误
SEVERE: Servlet [SpringDispatcher] in web application [/####] threw load() exception
java.lang.IllegalAccessException: Class org.springframework.core.io.support.SpringFactoriesLoader can not access a member of class org.springframework.data.jpa.util.HibernateProxyDetector with modifiers ""
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.Class.newInstance(Class.java:436)
at org.springframework.core.io.support.SpringFactoriesLoader.instantiateFactory(SpringFactoriesLoader.java:135)
at org.springframework.core.io.support.SpringFactoriesLoader.loadFactories(SpringFactoriesLoader.java:91)
at org.springframework.data.util.ProxyUtils.<clinit>(ProxyUtils.java:40)
at org.springframework.data.util.ClassTypeInformation.<init>(ClassTypeInformation.java:93)
at org.springframework.data.util.ClassTypeInformation.<clinit>(ClassTypeInformation.java:45)
at org.springframework.data.repository.core.support.AbstractRepositoryMetadata.<init>(AbstractRepositoryMetadata.java:58)
at org.springframework.data.repository.core.support.DefaultRepositoryMetadata.<init>(DefaultRepositoryMetadata.java:52)
at org.springframework.data.repository.core.support.AbstractRepositoryMetadata.getMetadata(AbstractRepositoryMetadata.java:73)
at org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport.getRepositoryConfigurations(RepositoryConfigurationExtensionSupport.java:99)
at org.springframework.data.repository.config.RepositoryConfigurationDelegate.registerRepositoriesIn(RepositoryConfigurationDelegate.java:145)
at org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions(RepositoryBeanDefinitionRegistrarSupport.java:85)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader.java:344)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:151)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:124)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:318)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:239)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:606)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:462)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:663)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:535)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:489)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1174)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:983)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4829)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5139)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1425)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1415)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:941)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:839)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1425)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1415)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:941)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:258)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:770)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Catalina.start(Catalina.java:671)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:353)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:493)
ApplicationContextConfig。java
@Configuration
@ComponentScan({"com.e*****e","com.*****re","com.db.master"})
@EnableWebMvc
@PropertySource({"classpath:db.properties", "classpath:log4j.properties", "classpath:fee2CommonProperties.properties", "classpath:examinations.properties", "classpath:security.properties",
"classpath:build.properties","classpath:commonProperties.properties","classpath:toaster.properties","classpath:screenReference.properties","classpath:socialLogin.properties"})
@EnableTransactionManagement
@Import({ WebSocketMessageBrokerConfigurer.class, WebSocketSecurityMessageBrokerConfigurer.class})
public class ApplicationContextConfig extends WebMvcConfigurerAdapter {
@Bean(name = "viewResolver")
public InternalResourceViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getHandlerInterceptor());
}
@Bean
Interceptor getHandlerInterceptor() {
return new Interceptor();
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
private Environment env;
@Bean
@Profile("Test")
public DataSource getDataSourceTest() {
System.out.println("test loaded");
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
String url="jdbc:mysql://localhost:3308/dbapi?useUnicode=true&characterEncoding=UTF-8";
dataSource.setUrl(url);
dataSource.setUsername("admin");
dataSource.setPassword("admin");
return dataSource;
/*return new EmbeddedDatabaseBuilder()
.setName("testdb;MODE=MySQL;DB_CLOSE_ON_EXIT=false")
.setType(EmbeddedDatabaseType.H2)
.build();*/
}
@Bean
public DozerBeanMapper beanMapper() {
final DozerBeanMapper mapper = new DozerBeanMapper();
return mapper;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/svg/**").addResourceLocations("/nxqLiteParent/svg/");
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("utf-8");
return resolver;
}
@Autowired
private RequestMappingHandlerAdapter adapter;
@PostConstruct
public void initCustomMessageConverter() {
List<HttpMessageConverter<?>> messageConverters = adapter.getMessageConverters();
BufferedImageHttpMessageConverter imageConverter = new BufferedImageHttpMessageConverter();;
messageConverters.add(0,imageConverter);
}
}
租户数据库配置。java
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = {"com.ed***re.dao","com.ed***re.fee.dao","com.ed***re.rest.dao"},
entityManagerFactoryRef = "tenantEntityManagerFactory",
transactionManagerRef = "tenantTransactionManager"
)
public class TenantDatabaseConfig {
private static final Logger LOG = LoggerFactory.getLogger(TenantDatabaseConfig.class);
@Bean(name = "tenantTransactionManager")
public JpaTransactionManager transactionManager(@Qualifier("tenantEntityManagerFactory") EntityManagerFactory tenantEntityManager) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(tenantEntityManager);
return transactionManager;
}
@Bean(name = "datasourceBasedMultitenantConnectionProvider")
public MultiTenantConnectionProvider multiTenantConnectionProvider() {
return new DataSourceBasedMultiTenantConnectionProviderImpl();
}
@Bean(name = "currentTenantIdentifierResolver")
public CurrentTenantIdentifierResolver currentTenantIdentifierResolver() {
return new CurrentTenantIdentifierResolverImpl();
}
@Autowired
@Bean(name = "tenantEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
@Qualifier("datasourceBasedMultitenantConnectionProvider") MultiTenantConnectionProvider connectionProvider,
@Qualifier("currentTenantIdentifierResolver") CurrentTenantIdentifierResolver tenantResolver) {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean emfBean = new LocalContainerEntityManagerFactoryBean();
emfBean.setPackagesToScan("com.testpro.model", "com.testpro.fee.model", "com.testpro.rest.model");
emfBean.setJpaVendorAdapter(vendorAdapter);
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.cache.use_second_level_cache", true);
properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");
properties.put(org.hibernate.cfg.Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
properties.put(org.hibernate.cfg.Environment.MULTI_TENANT_CONNECTION_PROVIDER, connectionProvider);
properties.put(org.hibernate.cfg.Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, tenantResolver);
properties.put(org.hibernate.cfg.Environment.DIALECT, "org.hibernate.dialect.MySQL5Dialect");
properties.put(org.hibernate.cfg.Environment.SHOW_SQL, true);
properties.put(org.hibernate.cfg.Environment.FORMAT_SQL, true);
properties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, "none");
emfBean.setJpaPropertyMap(properties);
LOG.info("tenantEntityManagerFactory set up successfully!");
return emfBean;
}
@Bean
public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setPackagesToScan("com.testpro.model", "com.testpro.fee.model", "com.testpro.rest.model");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put(org.hibernate.cfg.Environment.DIALECT, "org.hibernate.dialect.MySQL5Dialect");
properties.put(org.hibernate.cfg.Environment.SHOW_SQL, false);
properties.put(org.hibernate.cfg.Environment.FORMAT_SQL, true);
properties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, "false");
properties.put("hibernate.cache.use_second_level_cache", true);
properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");
properties.put(org.hibernate.cfg.Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
properties.put(org.hibernate.cfg.Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider());
properties.put(org.hibernate.cfg.Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver());
return properties;
}
}
MasterDatabaseConfig。java
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = "com.db.master.master.repository",
entityManagerFactoryRef = "masterEntityManagerFactory",
transactionManagerRef = "masterTransactionManager"
)
public class MasterDatabaseConfig {
private static final Logger LOG = LoggerFactory.getLogger(MasterDatabaseConfig.class);
@Bean(name = "masterDataSource")
public DataSource masterDataSource() {
LOG.info("Setting up masterDataSource with#############: ");
HikariDataSource ds = new HikariDataSource();
ds.setUsername("root");
ds.setPassword("root");
ds.setJdbcUrl("jdbc:mysql://localhost:3306/db14?useUnicode=true&characterEncoding=UTF-8");
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setPoolName("Master");
// HikariCP settings
// Maximum number of actual connection in the pool
ds.setMaximumPoolSize(10);
// Minimum number of idle connections in the pool
ds.setMinimumIdle(10);
// Maximum waiting time for a connection from the pool
ds.setConnectionTimeout(20000);
// Maximum time that a connection is allowed to sit idle in the pool
ds.setIdleTimeout(300000);
LOG.info("Setup of masterDataSource succeeded.");
return ds;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
return hibernateJpaVendorAdapter;
}
/*
* Here you can specify any provider specific properties.
*/
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put(org.hibernate.cfg.Environment.DIALECT,
"org.hibernate.dialect.MySQL5Dialect");
properties.put(org.hibernate.cfg.Environment.SHOW_SQL, true);
properties.put(org.hibernate.cfg.Environment.FORMAT_SQL, true);
properties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, "update");
return properties;
}
@Primary
@Bean(name = "masterEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean masterEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
// Set the master data source
em.setDataSource(masterDataSource());
// The master tenant entity and repository need to be scanned
em.setPackagesToScan(
new String[] { MasterTenant.class.getPackage().getName(),
MasterDAO.class.getPackage().getName() });
// Setting a name for the persistence unit as Spring sets it as
// 'default' if not defined
em.setPersistenceUnitName("masterdb-persistence-unit");
// Setting Hibernate as the JPA provider
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
// Set the hibernate properties
em.setJpaProperties(hibernateProperties());
LOG.info("Setup of masterEntityManagerFactory succeeded.");
return em;
}
@Autowired
@Primary
@Bean(name = "masterTransactionManager")
public JpaTransactionManager masterTransactionManager(
@Qualifier("masterEntityManagerFactory") EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
@Autowired
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(emf);
return txManager;
}
}
基于数据源的多租户连接提供商MPL。java
public class DataSourceBasedMultiTenantConnectionProviderImpl
extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
private static final long serialVersionUID = 1L;
/**
* Injected MasterTenantRepository to access the tenant information from the
* master_tenant table
*/
@Autowired
private MasterDAO masterDAO;
private Map<String, DataSource> dataSourcesMtApp = new TreeMap<>();
@Override
protected DataSource selectAnyDataSource() {
// This method is called more than once. So check if the data source map
// is empty. If it is then rescan master_tenant table for all tenant
// entries.
//System.out.println("Select any datasource");
if (dataSourcesMtApp.isEmpty()) {
//System.out.println("dataSourcesMtApp.isEmpty()");
List<MasterTenant> masterTenants = masterDAO.findAll();
for (MasterTenant masterTenant : masterTenants) {
dataSourcesMtApp.put(masterTenant.getTenantId(),
DataSourceUtil.createAndConfigureDataSource(masterTenant));
}
}
return this.dataSourcesMtApp.values().iterator().next();
}
@Override
protected DataSource selectDataSource(String tenantIdentifier) {
// If the requested tenant id is not present check for it in the master
// database 'master_tenant' table
//System.out.println("Select DataSource");
if (!this.dataSourcesMtApp.containsKey(tenantIdentifier)) {
//System.out.println("Select DataSource not contain key");
List<MasterTenant> masterTenants = masterDAO.findAll();
for (MasterTenant masterTenant : masterTenants) {
dataSourcesMtApp.put(masterTenant.getTenantId(),
DataSourceUtil.createAndConfigureDataSource(masterTenant));
}
}
return this.dataSourcesMtApp.get(tenantIdentifier);
}
}
大师刀。雅加瓦
@Repository
public interface MasterDAO extends JpaRepository<MasterTenant, Integer> {
@Override
public List<MasterTenant> findAll();
}
共 (0) 个答案