我一直在尝试让多个数据库系统在同一个Spring Boot项目中运行,但时间比预期更长。我一直遇到以下异常,并需要更多的帮助来解决问题。
很抱歉下面的代码量如此之大,但由于我不确定问题实际发生在哪里,因此我将所有内容都列了出来。
请注意:我正在使用专有的ERP数据库作为其中一个端点。该端点是一个Oracle数据库,只读。如果需要,我们可以将其切换到MySQL端点,但我的用例要求必须使用ERP的端点才能使项目成功。
使用的资源:
代码:
完整的堆栈跟踪:
很抱歉下面的代码量如此之大,但由于我不确定问题实际发生在哪里,因此我将所有内容都列了出来。
请注意:我正在使用专有的ERP数据库作为其中一个端点。该端点是一个Oracle数据库,只读。如果需要,我们可以将其切换到MySQL端点,但我的用例要求必须使用ERP的端点才能使项目成功。
使用的资源:
- 使用Spring Boot和Spring Data JPA管理多个数据库
- Spring Data管理多个数据库
- 使用Spring Data JPA管理多个数据库
- 使用Spring Boot管理多个数据库
- 使用Spring Boot和Spring Data管理多个数据源
- Spring Boot配置和使用两个数据源
- 如何在Spring Boot中使用两个数据源的数据访问
我相信我的答案可能仍然在上述内容之一中,但现在我离问题太近了,这就是我需要帮助的地方。
异常:
java.lang.IllegalArgumentException: Not a managed type: class com.xxx.ddbo.suiteanalytics.objects.ReturnsReasonBrand
代码:
application.properties
#Global properties for spring configuration
logging.level.org.apache=ERROR
logging.level.org.springframework=WARN
logging.level.org.hibernate=INFO
logging.level.org.hibernate.type=INFO
#Spring configuration
spring.jpa.show-sql=true
spring.jackson.property-naming-strategy=CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES
spring.jpa.hibernate.naming.strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.type=info
spring.jpa.generate-ddl=false
spring.jpa.database=default
## DATABASE CONFIGURATIONS
#Properties for PostgreSQL connection
spring.postgresql.datasource.url=xxxxxxxx
spring.postgresql.datasource.username=xxxxxxxx
spring.postgresql.datasource.password=xxxxxxxx
spring.postgresql.datasource.driver-class-name=org.postgresql.Driver
spring.postgresql.datasource.tomcat.max-active=50
#Properties for NetSuite SuiteAnalytics ODBC connection
#Sandbox URL
spring.suiteanalytics.datasource.url=xxxxxxxx
#Production URL
#spring.suiteanalytics.datasource.url=xxxxxxxx
spring.suiteanalytics.datasource.username=xxxxxxxx
spring.suiteanalytics.datasource.password=xxxxxxxx
spring.suiteanalytics.datasource.driver-class-name=com.netsuite.jdbc.openaccess.OpenAccessDriver
spring.suiteanalytics.datasource.tomcat.max-active=50
DdboApplication.java (ddbo)
@EnableJpaRepositories
@SpringBootApplication
@ComponentScan("com.xxx.ddbo")
public class DdboApplication implements CommandLineRunner{
@Autowired
private ReturnReasonsBrandRepository rrRepo;
@Autowired
private CustomListValuesRepository customListValuesRepository;
public static void main(String[] args) {
SpringApplication.run(DdboApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
CustomSegments cs = new CustomSegments(rrRepo);
cs.printReturnReasonBrand();
CustomLists cl = new CustomLists(customListValuesRepository);
cl.printCustomListValues();
}
}
PostgresqlConfig.java (ddbo.postgresql.configuration)
@Configuration
@EnableJpaRepositories(
basePackages = "com.xxx.ddbo.postgresql.interfaces",
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager"
)
public class PostgresqlConfig {
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties(prefix="spring.postgresql")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("dataSource") DataSource dataSource) {
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
return builder
.dataSource(dataSource)
.properties(properties)
.packages("com.xxx.ddbo.postgresql.interfaces")
.persistenceUnit("foo")
.build();
}
@Primary
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
CustomListValuesRepository.java (ddbo.postgresql.interfaces)
@Repository
public interface CustomListValuesRepository extends JpaRepository<CustomListValues,CustomListValuePkey>{
}
CustomLists.java (ddbo.postgresql.logic)
@Component
public class CustomLists {
private final CustomListValuesRepository customListValuesRepository;
@Autowired
public CustomLists(CustomListValuesRepository customListValuesRepository) {
this.customListValuesRepository = customListValuesRepository;
}
public void printCustomListValues(){
List<CustomListValues> values = customListValuesRepository.findAll();
for(CustomListValues value: values){
System.out.println(value.getValueText());
}
}
}
CustomLists.java (ddbo.postgresql.objects)
@Entity
@Table(name = "custom_lists")
public class CustomLists {
@Id
@Column
private String listIntId;
@Column
private String mongoId;
public CustomLists(String listIntId) {
this.listIntId = listIntId;
}
public CustomLists() {
}
public String getListIntId() {
return listIntId;
}
public void setListIntId(String listIntId) {
this.listIntId = listIntId;
}
public String getMongoId() {
return mongoId;
}
public void setMongoId(String mongoId) {
this.mongoId = mongoId;
}
}
CustomListValuePkey (ddbo.postgresql.objects)
@Embeddable
public class CustomListValuePkey implements Serializable {
@Column
private String listId;
@Column
private String valueIntId;
public String getListId() {
return listId;
}
public void setListId(String listId) {
this.listId = listId;
}
public String getValueIntId() {
return valueIntId;
}
public void setValueIntId(String valueIntId) {
this.valueIntId = valueIntId;
}
}
CustomListValues.java (ddbo.postgresql.objects)
@Entity
@Table(name = "custom_list_values")
public class CustomListValues implements Serializable {
@EmbeddedId
private CustomListValuePkey pkey;
@Column
private String valueText;
@ManyToOne
@JoinColumn(name = "listIntId")
private CustomLists listId;
public CustomLists getListId() {
return listId;
}
public void setListId(CustomLists listId) {
this.listId = listId;
}
public String getValueText() {
return valueText;
}
public void setValueText(String valueText) {
this.valueText = valueText;
}
public CustomListValuePkey getPkey() {
return pkey;
}
public void setPkey(CustomListValuePkey pkey) {
this.pkey = pkey;
}
}
SuiteAnalyticsConfig.java (ddbp.suiteanalytics.configuration)
@Configuration
@PropertySource({"classpath:application.properties"})
@EnableJpaRepositories(
basePackages = "com.xxx.ddbo.suiteanalytics.interfaces",
entityManagerFactoryRef = "suiteanalyticsEntityManagerFactory",
transactionManagerRef = "suiteanalyticsTransactionManager"
)
public class SuiteAnalyticsConfig {
@Bean(name = "nsDataSource")
@ConfigurationProperties(prefix="spring.suiteanalytics")
public DataSource nsDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "nsEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean nsEntityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("nsDataSource") DataSource nsDataSource) {
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
return builder
.dataSource(nsDataSource)
.properties(properties)
.packages("com.xxx.ddbo.suiteanalytics.interfaces")
.persistenceUnit("ReturnReasonsBrand")
.build();
}
@Bean(name = "nsTransactionManager")
public PlatformTransactionManager nsTransactionManager(
@Qualifier("nsEntityManagerFactory") EntityManagerFactory nsEntityManagerFactory) {
return new JpaTransactionManager(nsEntityManagerFactory);
}
}
ReturnReasonsBrandRepository.java (ddbo.suiteanalytics.interfaces)
@Repository
public interface ReturnReasonsBrandRepository extends JpaRepository<ReturnsReasonBrand,Integer> {
// ReturnsReasonBrand findOneByRrBrandId(Integer id);
}
CustomSegments.java (ddbo.suiteanalytics.logic)
@Component
public class CustomSegments {
private final ReturnReasonsBrandRepository rrRepo;
@Autowired
public CustomSegments(ReturnReasonsBrandRepository rrRepo) {
this.rrRepo = rrRepo;
}
public void printReturnReasonBrand(){
List<ReturnsReasonBrand> brand = rrRepo.findAll();
for(ReturnsReasonBrand rrBrand : brand){
System.out.println(rrBrand.getRrBrandName());
}
}
}
ReturnReasonsBrand.java (ddbo.suiteanalytics.objects)
@Entity
@Table(name = "rr_brand")
public class ReturnsReasonBrand {
@Id
@Column(name = "RR_BRAND_ID")
private Integer rrBrandId;
@Column(name = "RR_BRAND_NAME")
private String rrBrandName;
public Integer getRrBrandId() {
return rrBrandId;
}
public void setRrBrandId(Integer rrBrandId) {
this.rrBrandId = rrBrandId;
}
public String getRrBrandName() {
return rrBrandName;
}
public void setRrBrandName(String rrBrandName) {
this.rrBrandName = rrBrandName;
}
}
完整的堆栈跟踪:
2018-03-14 09:53:17.773 INFO 14512 --- [ main] com.xxx.ddbo.DdboApplication : Starting DdboApplication on xxx with PID xxx (started by roberth in xxx)
2018-03-14 09:53:17.775 INFO 14512 --- [ main] com.xxx.ddbo.DdboApplication : No active profile set, falling back to default profiles: default
2018-03-14 09:53:18.740 INFO 14512 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: CustomListValues
...]
2018-03-14 09:53:18.808 INFO 14512 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.0.12.Final}
2018-03-14 09:53:18.809 INFO 14512 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2018-03-14 09:53:18.810 INFO 14512 --- [ main] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2018-03-14 09:53:18.848 INFO 14512 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-03-14 09:53:19.130 INFO 14512 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
2018-03-14 09:53:19.365 INFO 14512 --- [ main] o.h.e.j.e.i.LobCreatorBuilderImpl : HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
2018-03-14 09:53:19.366 INFO 14512 --- [ main] org.hibernate.type.BasicTypeRegistry : HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType@3249a1ce
2018-03-14 09:53:19.503 WARN 14512 --- [ main] org.hibernate.mapping.RootClass : HHH000038: Composite-id class does not override equals(): com.xxx.ddbo.postgresql.objects.CustomListValuePkey
2018-03-14 09:53:19.503 WARN 14512 --- [ main] org.hibernate.mapping.RootClass : HHH000039: Composite-id class does not override hashCode(): com.xxx.ddbo.postgresql.objects.CustomListValuePkey
2018-03-14 09:53:19.698 INFO 14512 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: ReturnReasonsBrand
...]
2018-03-14 09:53:35.120 INFO 14512 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
2018-03-14 09:53:36.268 INFO 14512 --- [ main] o.h.e.j.e.i.LobCreatorBuilderImpl : HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
2018-03-14 09:53:36.434 WARN 14512 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ddboApplication': Unsatisfied dependency expressed through field 'rrRepo'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'returnReasonsBrandRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.xxx.ddbo.suiteanalytics.objects.ReturnsReasonBrand
2018-03-14 09:53:41.730 ERROR 14512 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ddboApplication': Unsatisfied dependency expressed through field 'rrRepo'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'returnReasonsBrandRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.xxx.ddbo.suiteanalytics.objects.ReturnsReasonBrand
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
at com.xxx.ddbo.DdboApplication.main(DdboApplication.java:26) [classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'returnReasonsBrandRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.xxx.ddbo.suiteanalytics.objects.ReturnsReasonBrand
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
... 18 common frames omitted
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.xxx.ddbo.suiteanalytics.objects.ReturnsReasonBrand
at org.hibernate.jpa.internal.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:210) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:70) ~[spring-data-jpa-1.11.10.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:68) ~[spring-data-jpa-1.11.10.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:173) ~[spring-data-jpa-1.11.10.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:106) ~[spring-data-jpa-1.11.10.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:88) ~[spring-data-jpa-1.11.10.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:198) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:277) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:263) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:101) ~[spring-data-jpa-1.11.10.RELEASE.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
... 28 common frames omitted
SuiteAnalyticsConfig
上的entityManagerFactoryRef
和transactionManagerRef
值实际上与您创建的bean名称不匹配。 - Strelok