简体   繁体   English

Spring Boot Data JPA与DB / 2 Configuration和JUnit有关

[英]Spring Boot Data JPA issues with DB/2 Configuration and JUnit

I am working on a project which wants to use spring-boot-data-jpa. 我正在开发一个想要使用spring-boot-data-jpa的项目。 The local (IDE) database can be H2. 本地(IDE)数据库可以是H2。 However, for all servers (dev/test/prod), we are forced to use DB/2 (unfortunately!). 但是,对于所有服务器(dev / test / prod),我们不得不使用DB / 2(不幸的是!)。

We can't seem to get it things working with DB/2. 我们似乎无法使用DB / 2。 We get an error like this: 我们得到这样的错误:

java.lang.IllegalStateException: Failed to load ApplicationContext....
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No   
qualifying bean of type [...Repository] found for
dependency: expected at least 1 bean which qualifies as autowire candidate for this 
dependency. Dependency annotations: {}

when running the unit tests (JUnit). 在运行单元测试时(JUnit)。 Note, the blank {} annotation. 注意,空白{}注释。 Which on the face of it seems like an "obvious" issue. 从表面看来,这似乎是一个“明显”的问题。 The repository bean can not be loaded or found on the classpath. 无法在类路径中加载或找到存储库bean。 However, when we run this with H2 configuration, it works just fine. 但是,当我们使用H2配置运行它时,它可以正常工作。

So, the next logical conclusion seems to be the repositories configuration (data source, etc.) is not set up correctly. 因此,下一个逻辑结论似乎是存储库配置(数据源等)未正确设置。 However, we can use the same configuration values in a non spring boot application and it works fine! 但是,我们可以在非Spring启动应用程序中使用相同的配置值,它工作正常!

So then I was thinking it could be something with the either the differing classloaders or cglib proxies not using the "real" implementation class. 所以我认为它可能是不同的类加载器或cglib代理不使用“真正的”实现类。 SO questions like these: 这样的问题:

However, the correct answers for those questions do not resolve the issue. 但是,这些问题的正确答案无法解决问题。 So here is my post/question. 所以这是我的帖子/问题。

How do figure out the root cause of this issue? 如何找出这个问题的根本原因? I have tried to walk through the code (spring and our code) in the debugger but can't narrow down a cause. 我试图在调试器中遍历代码(spring和我们的代码),但无法缩小原因。

So then I tried this, I took the sample spring boot jpa and modified it to use specific properties for DB/2 and I can get the same failure. 所以我试过这个,我拿了示例spring boot jpa并修改它以使用DB / 2的特定属性,我可以得到同样的失败。 So it seems like my configuration must be wrong or there is a bug in the spring code. 因此,我的配置似乎一定是错误的,或者Spring代码中存在错误。 I have looked at the configuration with someone else and we don't see the problem. 我已经与其他人一起查看了配置,但我们没有看到问题。 We tried this configuration in another (non-spring boot app) and it works. 我们在另一个(非春季启动应用程序)中尝试了此配置并且它可以工作。

Here is a patch file that shows the differences between the original jpa sample and the modified one with the configuration changes. 这是一个补丁文件 ,显示原始jpa示例与修改后的配置更改之间的差异。 Note, we removed the DB2 server details. 注意,我们删除了DB2服务器的详细信息。 Hopefully, this makes the issue reproducible for anyone and then can assist in figuring out the cause. 希望这使得问题可以为任何人重现,然后可以帮助找出原因。

TIA, TIA,

Scott 斯科特

edit 1 --- add configuration details here directly instead of a patch file --- 编辑1 ---在这里直接添加配置细节而不是补丁文件---

Java Configuration Java配置

@Configuration
@ComponentScan
@EnableAutoConfiguration
@PropertySource("classpath:application.properties")
public class SampleDataJpaApplication {

     public static void main(String[] args) throws Exception {
     SpringApplication.run(SampleDataJpaApplication.class, args);
     }
 }

Properties File 属性文件

spring.jpa.hibernate.naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.hibernate.dialect: org.hibernate.dialect.DB2Dialect
#spring.jpa.database-platform: DB2Platform
spring.jpa.show-sql: true
spring.jpa.generate-ddl: true

spring.datasource.driverClassName: om.ibm.db2.jcc.DB2Driver
spring.datasource.url: jdbc:db2:someDB2-db:5000
spring.datasource.username: fakeuser
spring.datasource.password: fakepassword
spring.datasource.schema:schema-name

Unit Test Configuration 单元测试配置

@RunWith(SpringJUnit4ClassRunner.class)
@PropertySource("classpath:application.properties")
@ContextConfiguration(classes = SampleDataJpaApplication.class, loader =       AnnotationConfigContextLoader.class)
public class CityRepositoryIntegrationTests {
 //....
}     

This should be nearly identical to the patch file just changing the user/password/jdbc URL to hide the specifics of the environment. 这应该与仅修改用户/密码/ jdbc URL的修补程序文件几乎相同,以隐藏环境的细节。

As far as I can see, the JUnit setup is not correct. 据我所知,JUnit设置不正确。 To let Boot work correctly you have two choices: 要让Boot正常工作,您有两种选择:

  1. Use @SpringApplicationConfiguration instead of @ContextConfiguration 使用@SpringApplicationConfiguration而不是@ContextConfiguration

    Boot configures the ApplicationContext bootstrap process quite a bit, eg to enable the default configuration files being picked up. Boot会相当多地配置ApplicationContext引导过程,例如,启用默认配置文件。 Using the custom annotation will automatically activate that stuff for the JUnit executions as well. 使用自定义注释也会自动激活JUnit执行的内容。

  2. Configure @ContextConfiguration with the appropriate listeners yourself 自己配置@ContextConfiguration和相应的侦听器

    In your case you at least need the ConfigFileApplicationContextInitializer in addition to all the default ones registered. 在您的情况下,除了注册的所有默认值之外,您至少需要ConfigFileApplicationContextInitializer

As the second option is rather cumbersome, I highly recommend to go with option one and see where that leads you. 由于第二个选项相当繁琐,我强烈建议选择第一个选项,看看它在哪里引导你。

Oliver, 奥利弗,

I can't seem to find the annotation @SpringApplicationConfiguration using the spring-boot-starter-test JAR as defined in the how-to. 我似乎@SpringApplicationConfiguration使用how-to中定义的spring-boot-starter-test JAR找到注释@SpringApplicationConfiguration I'm using spring boot 0.5.0.M6. 我正在使用弹簧靴0.5.0.M6。 Below are the dependencies in my Maven POM. 以下是我的Maven POM中的依赖项。 Anything I'm missing here? 我在这里缺少什么?

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>4.0.0.RELEASE</version>
</dependency>

EDIT : After looking through the Spring Boot sample projects I found a different approach to getting Junit and Spring test to play nicely with each other. 编辑 :在查看Spring Boot示例项目后,我发现了一种不同的方法来让Junit和Spring测试相互配合。 If you can define your class like the following things should work identical to what Oliver has mentioned in his reply for option 1. Notice the "loader" argument needs to be present to correctly configure listeners and backing beans correctly. 如果您可以像下面这样定义您的类,那么它应该与Oliver在其对选项1的回复中提到的相同。请注意,需要存在“loader”参数才能正确配置侦听器和支持bean。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MyDataApplication.class, loader = SpringApplicationContextLoader.class)
public class MyServiceTest {

I have similar problem with integration tests in Spring Boot and I can confirm @user3166395 solution. 我在Spring Boot中遇到类似的集成测试问题,我可以确认@ user3166395解决方案。

This configuration works for me: 这个配置对我有用:

import org.springframework.boot.test.SpringApplicationContextLoader;
import org.springframework.test.context.ContextConfiguration;
...

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MyDataApplication.class, loader = SpringApplicationContextLoader.class)
public class MyServiceTest {

   @Autowired
   CityRepository cityRepository;

}

This requires test dependency to: 这需要测试依赖性:

org.springframework.boot:spring-boot-starter-test:0.5.0.M7

I cant achieve working test with SpringApplicationConfiguration 我无法使用SpringApplicationConfiguration实现工作测试

Hey guys a little late to the party but to be clear about your error (since I copied it, I had the same): 嘿伙计们晚了一点,但要清楚你的错误(因为我复制了它,我也有同样的情况):

spring.datasource.driverClassName: **om**.ibm.db2.jcc.DB2Driver

should be 应该

spring.datasource.driverClassName: **com**.ibm.db2.jcc.DB2Driver

This worked for me so far. 到目前为止,这对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM