问题描述
我们在Spring Boot,JPA和Data Rest中使用多租户。我们有一个包含租户实体的Admin数据源。位于Admin数据源中的Tenant实体包含租户及其关联的数据源(MySql中的方案)之间的映射。当我们使用Spring Boot 2.1.6时,该应用程序运行良好。但是在我们迁移到Spring Boot 2.2.0之后,它崩溃了。
问题的表现:
GET请求http:// localhost:31337 / admin / tenants?size = 10&page = 0曾经返回200 OK,但现在它返回404 Not-Found。
在使用Spring Boot 2.1.16运行我们的应用程序时,我们经常看到以下调试日志,但是在Spring Boot 2.2.0中不再看到该日志。
[main] .s.d.r.c.RepositoryConfigurationDelegate:Spring Data JPA-注册存储库:tenantRepository-接口:
这是我们的Spring Boot应用程序类:
package com.compx.depx.appx.service.admin;
@SpringBootApplication
@ComponentScan({"com.compx.depx.appx.service.admin","com.compx.depx.appx.service.common.admin","com.compx.depx.appx.service.common.jpa"})
@EnableResourceServer
@EnableJpaRepositories(basePackages = "com.compx.depx.appx.service.admin.controller",entityManagerFactoryRef = "adminEntityManagerFactory",transactionManagerRef = "adminTransactionManager")
public class AdminServiceApplication {
public static void main(String[] args) {
SpringApplication.run(AdminServiceApplication.class,args);
}
}
在Spring Boot应用程序的子包中,我们定义了Tenant REST存储库,如下所示:
package com.compx.depx.appx.service.admin.controller;
import com.compx.depx.appx.data.entity.admin.Tenant;
@RepositoryRestResource
public interface TenantRestResource extends PagingAndSortingRepository<Tenant,Integer> {
Page<Tenant> findAllByTenantIdContainingIgnoreCase(@Param("tenantId") String tenantId,Pageable pageable);
Page<Tenant> findAllByNameContainingIgnoreCase(@Param("name") String name,Pageable pageable);
}
我们已经在一个单独的Java包中定义了Tenant实体,如下所示:
package com.compx.depx.appx.data.entity.admin;
@Entity
@Data
public class Tenant {
@Id
@GeneratedValue
private Integer id;
private String schemaName;
@Column(unique = true)
@NotNull
private String name;
@Column
private String tenantId;
}
我们还有一个用于JPA交易的Tenant存储库界面,如下所示:
package com.compx.depx.appx.data.repository.admin;
@Transactional("admin")
public interface TenantRepository extends Repository<Tenant,Integer> {
Optional<Tenant> findByTenantId(String tenantId);
Optional<Tenant> findById(Integer id);
}
我们已经定义了一个提供程序,它为我们提供了Admin DataSource的EntityManagerFactoryBean和TransactionManager,如下所示:
package com.compx.depx.appx.service.common.admin;
@Configuration
@RequiredArgsConstructor
@EntityScan(basePackages = "com.compx.depx.appx.data.entity.admin")
@EnableJpaRepositories(basePackages = {
"com.compx.depx.appx.data.repository.admin" },transactionManagerRef = "adminTransactionManager")
public class AdminProvider {
private final DataSourceProperties dataSourceProperties;
@Bean
@Primary
@Qualifier("admin")
public DataSource adminDataSource() {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean adminEntityManagerFactory(EntityManagerFactoryBuilder builder,List<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers) {
Map<String,Object> props = new HashMap<>();
for (HibernatePropertiesCustomizer customizer : hibernatePropertiesCustomizers) {
customizer.customize(props);
}
return builder.dataSource(adminDataSource()).packages("com.compx.depx.appx.data.entity.admin").persistenceUnit("admin").properties(props).build();
}
@Bean
@Qualifier("admin")
public PlatformTransactionManager adminTransactionManager(EntityManagerFactoryBuilder builder,List<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(adminEntityManagerFactory(builder,hibernatePropertiesCustomizers).getObject());
return transactionManager;
}
}
我们还使用一个类为MySql ... etc自定义Hibernate属性。
package com.compx.depx.appx.service.common.jpa;
@Configuration
@RequiredArgsConstructor
@EnableJpaAuditing
public class JpaConfiguration {
private final JpaProperties properties;
private final HibernateProperties hibernateProperties;
@Bean
public Validator validator() {
return new LocalValidatorFactoryBean();
}
@Bean
public HibernatePropertiesCustomizer hibernateCustomizer() {
return (props) -> {
properties.getProperties(),new HibernateSettings());
props.putAll(newProps);
props.put(AvailableSettings.JPA_VALIDATION_FACTORY,validator());
if (!props.containsKey(AvailableSettings.DIALECT)) {
String dialect = properties.getDatabasePlatform();
if (dialect == null) {
dialect = "org.hibernate.dialect.MySQL57Dialect";
}
props.put(AvailableSettings.DIALECT,dialect);
}
if (properties.isGenerateDdl()) {
props.put(AvailableSettings.HBM2DDL_AUTO,"update");
}
props.put(AvailableSettings.PHYSICAL_NAMING_STRATEGY,"org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
};
}
}
使用Spring 5.0.10和Spring Boot 2.0.6的工作应用程序中的调试日志
2020-08-23 23:09:10.889调试20 --- [main] .s.d.r.c.RepositoryConfigurationDelegate:扫描包com.compx.depx.appx.data.repository.admin中的存储库。 2020-08-23 23:09:10.910调试20 --- [main] osdrcRepositoryComponentProvider:标识的候选组件类:URL [jar:file:/appx/app.jar!/ BOOT-INF / lib / appx-reporting- data-2018.1-SNAPSHOT.jar!/com/compx/depx/appx/data/repository/admin/TenantRepository.class] 2020-08-23 23:09:11.028调试20 --- [main] .sdrcRepositoryConfigurationDelegate:Spring Data JPA-注册存储库:tenantRepository-接口:com.compx.depx.appx.data.repository.admin.TenantRepository-工厂:org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean 2020-08-23 23:09:11.029调试20 --- [main] .s.d.r.c.RepositoryConfigurationDelegate:完成存储库扫描。 2020-08-23 23:09:11.032调试20 --- [main] .s.d.r.c.RepositoryConfigurationDelegate:扫描com.compx.depx.appx.appx.service.admin.controller软件包中的存储库。 2020-08-23 23:09:11.036调试20 --- [main] osdrcRepositoryComponentProvider:识别出的候选组件类:URL [jar:file:/appx/app.jar!/ BOOT-INF / classes!/ com / compx /depx/appx/service/admin/controller/TenantRestResource.class] 2020-08-23 23:09:11.057调试20 --- [main] .sdrcRepositoryConfigurationDelegate:Spring Data JPA-注册存储库:tenantRestResource-接口:com.compx.depx.appx.service.admin.controller.TenantRestResource-工厂:org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean 2020-08-23 23:09:11.058调试20 --- [main] .s.d.r.c.RepositoryConfigurationDelegate:完成存储库扫描。
2020-08-23 23:10:17.401调试20 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor:在OpenEntityManagerInViewInterceptor中打开JPA EntityManager 2020-08-23 23:10:17.404调试20 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet:空ModelAndView返回到名称为'dispatcherServlet'的DispatcherServlet:假设HandlerAdapter完成了请求处理 2020-08-23 23:10:17.404调试20 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor:在OpenEntityManagerInViewInterceptor中关闭JPA EntityManager 2020-08-23 23:10:17.405调试20 --- [nio-8080-exec-1] o.s.orm.jpa.EntityManagerFactoryUtils:关闭JPA EntityManager 2020-08-23 23:10:17.405调试20 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet:成功完成请求
使用Spring 5.2.8和Spring Boot 2.3.3从损坏的应用程序中调试日志
2020-08-19 17:25:59.220信息20 --- [main] .s.d.r.c.RepositoryConfigurationDelegate:以DEFAULT模式引导Spring Data JPA存储库。 2020-08-19 17:25:59.246调试20 --- [main] .s.d.r.c.RepositoryConfigurationDelegate:扫描com.compx.depx.appx.datax.repository.admin包中的JPA存储库。 2020-08-19 17:25:59.262调试20 --- [main] osdrcRepositoryComponentProvider:确定的候选组件类:URL [jar:file:/appx/app.jar!/ BOOT-INF / lib / appx-reporting- data-2018.1-SNAPSHOT.jar!/com/compx/depx/appx/data/repository/admin/TenantRepository.class] 2020-08-19 17:25:59.404信息20-[[main] .s.d.r.c.RepositoryConfigurationDelegate:在157毫秒内完成Spring Data信息库扫描。找到1个JPA存储库接口。 2020-08-19 17:25:59.409信息20-[[main] .s.d.r.c.RepositoryConfigurationDelegate:在默认模式下引导Spring Data JPA存储库。 2020-08-19 17:25:59.409调试20 --- [main] .s.d.r.c.RepositoryConfigurationDelegate:扫描com.compx.depx.appx.appx.service.admin.controller包中的JPA存储库。 2020-08-19 17:25:59.414调试20 --- [main] osdrcRepositoryComponentProvider:标识的候选组件类:URL [jar:file:/appx/app.jar!/ BOOT-INF / classes!/ com / compx /depx/appx/service/admin/controller/TenantRestResource.class] 2020-08-19 17:25:59.454信息20-[[main] .s.d.r.c.RepositoryConfigurationDelegate:在45毫秒内完成Spring Data信息库扫描。找到1个JPA存储库接口。
2020-08-19 17:32:37.512调试20 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy:/ tenants?size = 10&page = 0到达附加过滤器链的末尾;继续原始链 2020-08-19 17:32:37.513调试20 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet:GET“ / tenants?size = 10&page = 0”,参数= {masked} 2020-08-19 17:32:37.516调试20 --- [nio-8080-exec-7] oswshandler.SimpleUrlHandlerMapping:映射到ResourceHttpRequestHandler [“ classpath:/ META-INF / resources /”,“ classpath:/ resources /“,” classpath:/ static /“,” classpath:/ public /“,” /“] 2020-08-19 17:32:37.517调试20 --- [nio-8080-exec-7] o.j.s.OpenEntityManagerInViewInterceptor:在OpenEntityManagerInViewInterceptor中打开JPA EntityManager 2020-08-19 17:32:37.520调试20 --- [nio-8080-exec-7] o.s.w.s.r.ResourceHttpRequestHandler:找不到资源 2020-08-19 17:32:37.521调试20 --- [nio-8080-exec-7] o.j.s.OpenEntityManagerInViewInterceptor:在OpenEntityManagerInViewInterceptor中关闭JPA EntityManager 2020-08-19 17:32:37.521调试20 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet:已完成404 NOT_FOUND
值得注意的区别是在工作版本上发生但在非工作版本中缺少的“ RepositoryConfigurationDelegate:Spring Data JPA-注册存储库:”日志。
我们已经尽可能检查了引入的库及其依赖项。我们感谢任何提示或指示可能导致此问题的原因。如果需要更多信息,请告诉我。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)