Java DB/2 配置和 JUnit 的 Spring Boot Data JPA 问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20748658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 04:04:23  来源:igfitidea点击:

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

javaspringjunitspring-dataautowired

提问by Scott C.

I am working on a project which wants to use spring-boot-data-jpa. The local (IDE) database can be H2. However, for all servers (dev/test/prod), we are forced to use DB/2 (unfortunately!).

我正在开发一个想要使用 spring-boot-data-jpa 的项目。本地 (IDE) 数据库可以是 H2。然而,对于所有服务器(开发/测试/生产),我们不得不使用 DB/2(不幸的是!)。

We can't seem to get it things working with DB/2. We get an error like this:

我们似乎无法让它与 DB/2 一起工作。我们得到这样的错误:

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). 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. However, when we run this with H2 configuration, it works just fine.

运行单元测试 (JUnit) 时。请注意,空白的 {} 注释。从表面上看,这似乎是一个“明显”的问题。无法在类路径上加载或找到存储库 bean。但是,当我们使用 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. SO questions like these:

所以我想这可能是因为不同的类加载器或 cglib 代理不使用“真正的”实现类。像这样的问题:

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. So it seems like my configuration must be wrong or there is a bug in the spring code. 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.

然后我尝试了这个,我采用了示例 spring boot jpa 并将其修改为使用 DB/2 的特定属性,我可以得到同样的失败。所以看起来我的配置肯定是错误的,或者spring代码有bug。我已经和其他人一起查看了配置,我们没有看到问题。我们在另一个(非 spring 启动应用程序)中尝试了这个配置并且它有效。

Here is a patch filethat shows the differences between the original jpa sample and the modified one with the configuration changes. Note, we removed the DB2 server details. Hopefully, this makes the issue reproducible for anyone and then can assist in figuring out the cause.

这是一个补丁文件,显示了原始 jpa 示例和经过配置更改的修改后的示例之间的差异。请注意,我们删除了 DB2 服务器详细信息。希望这可以使任何人都可以重现该问题,然后可以帮助找出原因。

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 以隐藏环境的细节。

采纳答案by user3166395

Oliver,

奥利弗,

I can't seem to find the annotation @SpringApplicationConfigurationusing the spring-boot-starter-test JAR as defined in the how-to. I'm using spring boot 0.5.0.M6. Below are the dependencies in my Maven POM. Anything I'm missing here?

我似乎无法@SpringApplicationConfiguration使用方法中定义的 spring-boot-starter-test JAR找到注释。我正在使用弹簧靴 0.5.0.M6。以下是我的 Maven POM 中的依赖项。我在这里缺少什么吗?

<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. 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.

编辑:在查看 Spring Boot 示例项目后,我发现了一种不同的方法来让 Junit 和 Spring 测试相互配合。如果你可以像下面那样定义你的类,那么事情应该与 Oliver 在他对选项 1 的回复中提到的相同。注意“loader”参数需要存在才能正确配置侦听器和支持 bean。

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

回答by Oliver Drotbohm

As far as I can see, the JUnit setup is not correct. To let Boot work correctly you have two choices:

据我所知,JUnit 设置不正确。要让 Boot 正常工作,您有两个选择:

  1. Use @SpringApplicationConfigurationinstead of @ContextConfiguration

    Boot configures the ApplicationContextbootstrap process quite a bit, e.g. to enable the default configuration files being picked up. Using the custom annotation will automatically activate that stuff for the JUnit executions as well.

  2. Configure @ContextConfigurationwith the appropriate listeners yourself

    In your case you at least need the ConfigFileApplicationContextInitializerin addition to all the default ones registered.

  1. 使用@SpringApplicationConfiguration代替@ContextConfiguration

    Boot 对ApplicationContext引导过程进行了相当多的配置,例如启用默认配置文件。使用自定义注解也会自动为 JUnit 执行激活那些东西。

  2. @ContextConfiguration自己配置合适的监听器

    在您的情况下,您至少需要ConfigFileApplicationContextInitializer除了所有已注册的默认值之外。

As the second option is rather cumbersome, I highly recommend to go with option one and see where that leads you.

由于第二个选项相当麻烦,我强烈建议您选择第一个选项,看看它会引导您走向何方。

回答by MariuszS

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

回答by theFan

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.

到目前为止,这对我有用。