Java DB/2配置和JUnit的Spring引导数据JPA问题

Java DB/2配置和JUnit的Spring引导数据JPA问题,java,spring,junit,spring-data,autowired,Java,Spring,Junit,Spring Data,Autowired,我正在从事一个项目,希望使用spring引导数据jpa。本地(IDE)数据库可以是H2。然而,对于所有服务器(dev/test/prod),我们不得不使用DB/2(不幸的是!) 我们似乎无法让它与DB/2一起工作。我们得到如下错误: java.lang.IllegalStateException: Failed to load ApplicationContext.... Caused by: org.springframework.beans.factory.NoSuchBeanDefinit

我正在从事一个项目,希望使用spring引导数据jpa。本地(IDE)数据库可以是H2。然而,对于所有服务器(dev/test/prod),我们不得不使用DB/2(不幸的是!)

我们似乎无法让它与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: {}
运行单元测试(JUnit)时。注意,空白{}注释。从表面上看,这似乎是一个“显而易见”的问题。无法在类路径上加载或找到存储库bean。然而,当我们使用H2配置运行它时,它工作得很好

因此,下一个逻辑结论似乎是存储库配置(数据源等)设置不正确。但是,我们可以在非spring引导应用程序中使用相同的配置值,而且效果很好

所以,我当时认为可能是不同的类加载器或cglib代理并没有使用“真正的”实现类。所以像这样的问题:

但是,这些问题的正确答案并不能解决问题。这是我的帖子/问题

你如何找出这个问题的根本原因?我尝试在调试器中浏览代码(spring和我们的代码),但无法缩小原因

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

下面是一个示例,它显示了原始jpa示例和修改后的jpa示例在配置更改时的差异。注意,我们删除了DB2服务器的详细信息。希望这能让任何人都能重复这个问题,然后帮助找出原因

蒂亚

斯科特

编辑1---直接在此处添加配置详细信息,而不是补丁文件---

Java配置

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

     public static void main(String[] args) throws Exception {
     SpringApplication.run(SampleDataJpaApplication.class, args);
     }
 }
@RunWith(SpringJUnit4ClassRunner.class)
@PropertySource("classpath:application.properties")
@ContextConfiguration(classes = SampleDataJpaApplication.class, loader =       AnnotationConfigContextLoader.class)
public class CityRepositoryIntegrationTests {
 //....
}     
属性文件

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
单元测试配置

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

     public static void main(String[] args) throws Exception {
     SpringApplication.run(SampleDataJpaApplication.class, args);
     }
 }
@RunWith(SpringJUnit4ClassRunner.class)
@PropertySource("classpath:application.properties")
@ContextConfiguration(classes = SampleDataJpaApplication.class, loader =       AnnotationConfigContextLoader.class)
public class CityRepositoryIntegrationTests {
 //....
}     

这应该与补丁文件几乎相同,只是更改user/password/jdbc URL以隐藏环境的细节

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

  • 使用
    @SpringApplicationConfiguration
    而不是
    @ContextConfiguration

    Boot在很大程度上配置了
    ApplicationContext
    bootstrap过程,例如启用正在拾取的默认配置文件。使用自定义注释也会自动为JUnit执行激活这些内容

  • 自己使用适当的侦听器配置
    @ContextConfiguration

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

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

    Oliver

    我似乎找不到注释
    @SpringApplicationConfiguration
    ,它使用的是how-to中定义的springbootstarter测试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>
    

    我在Spring Boot中的集成测试中也有类似的问题,我可以确认@user3166395解决方案

    此配置适用于我:

    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;
    
    }
    
    这要求测试依赖性:

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

    我无法使用
    SpringApplicationConfiguration

    来完成工作测试嘿,大家来晚了一点,但为了清楚您的错误(因为我复制了它,所以我有相同的错误):

    应该是

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

    到目前为止,这对我很有效。

    分享您的配置会很有帮助。@OliverGierke-谢谢您的快速回复。我已经提供了一个补丁文件,该文件将通过包括配置在内的所有更改来更改spring数据示例应用程序。这对你有用吗?直接在这里发布Java配置会更好吗?请在这里发布您的配置。@OliverGierke-更新了帖子,以内联对示例JPA应用程序所做的配置更改。这些应与提供的补丁相同。让我知道我还能提供什么来更进一步地找出根本原因ScottWhat是@SpringApplicationConfiguration?请参阅。在基于启动的应用程序的集成测试中,它有效地替代了
    @ContextConfiguration
    。您可以通过包含
    spring boot starter test
    spring boot
    JAR以及分类器
    tests
    来拉入JAR。谢谢!)在你的帖子之后,我发现这是一个很好的例子,尽管它实际上早于
    @SpringApplicationConfiguration
    的创建日期(并且实际上允许创建)。你能用
    @SpringApplicationConfiguration
    发布示例吗?这不适合我。