Java 为什么H2数据库告诉我我的表不存在,只用于某些测试

Java 为什么H2数据库告诉我我的表不存在,只用于某些测试,java,spring,jpa,h2,Java,Spring,Jpa,H2,我有一个SpringJPA存储库,我正试图使用内存中的H2数据库来测试它。一些测试通过了,而另一些测试没有通过。问题是H2告诉我我的表不存在,这很奇怪,因为通过的测试也使用相同的表 以下是我的数据库配置: @Configuration @Import({BaseConfiguration.class, DatabaseProperties.class}) @EnableJpaRepositories(basePackages = DatabaseConfiguration.REPOSITORIE

我有一个SpringJPA存储库,我正试图使用内存中的H2数据库来测试它。一些测试通过了,而另一些测试没有通过。问题是H2告诉我我的表不存在,这很奇怪,因为通过的测试也使用相同的表

以下是我的数据库配置:

@Configuration
@Import({BaseConfiguration.class, DatabaseProperties.class})
@EnableJpaRepositories(basePackages = DatabaseConfiguration.REPOSITORIES_PACKAGE)
public class DatabaseConfiguration {

    /*
     * Constants
     */
    public static final String MODEL_PACKAGE = "be.dupirefr.examples.spring.batch.simple.model";
    public static final String REPOSITORIES_PACKAGE = "be.dupirefr.examples.spring.batch.simple.repositories";

    /*
     * Beans
     */
    @Bean
    public DataSource dataSource(DatabaseProperties properties) {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl(properties.url);
        dataSource.setUsername(properties.username);
        dataSource.setPassword(properties.password);
        dataSource.setDriverClassName(properties.driverClassName);

        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource);
        entityManagerFactoryBean.setPackagesToScan(MODEL_PACKAGE);
        entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        return entityManagerFactoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

}
上一个配置类中使用的属性存储在映射到以下配置类的database.properties文件中:

@Configuration
@PropertySource("classpath:be/dupirefr/examples/spring/batch/simple/config/database/database.properties")
public class DatabaseProperties {

    /*
     * Fields
     */
    @Value("${spring.datasource.url}")
    public String url;

    @Value("${spring.datasource.username}")
    public String username;

    @Value("${spring.datasource.password}")
    public String password;

    @Value("${spring.datasource.driver-class-name}")
    public String driverClassName;

}
此文件使用database.properties文件中的属性:

spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=admin
spring.datasource.password=admin
spring.datasource.driver-class-name=org.h2.Driver
以下是Employer类及其存储库测试类:

雇主:

@Entity
public class Employer {

    /*
     * Fields
     */
    @Id
    private Long id;

    @Column(nullable = false)
    private String name;

    @OneToMany(mappedBy = "employer")
    private List<Employee> employees;

    /*
     * Constructors
     */
    private Employer() {}

    public Employer(Long id, String name) {
        this.id = id;
        this.name = name;

        this.employees = new ArrayList<>();
    }

    /*
     * Getters
     */
    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    /*
     * Methods
     */
    //...

}
因为我只测试JpaRepository方法,所以我不使用EmployeerRepository接口,它在这里没有附加值

在上面显示的测试中,只有findById_存在,delete正在工作。对于其他人,我得到了以下错误:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [select employer0_.id as id1_2_0_, employer0_.name as name2_2_0_ from Employer employer0_ where employer0_.id=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
这似乎是由以下原因造成的:

org.h2.jdbc.JdbcSQLException: Table "EMPLOYER" not found; SQL statement:
从Employer employer0中选择employer0.id作为id1\u 2\u 0\u,employer0\u.name作为name2\u 2\u 0\u,其中employer0\u.id=?[42102-187]

我还尝试了以下数据库url:

你知道问题出在哪里吗

jdbc:h2:mem:test;DB_CLOSE_DELAY=-1

jdbc:h2:mem:test;DB_CLOSE_ON_EXIT=FALSE
但没有一个成功

编辑: 我想出了一些办法。失败的测试是那些实际到达数据库的测试。其他的只是在EntityManager的缓存中执行。看来我的问题在于H2数据库配置或类似的东西。我会查一查,但如果有人有主意,我会欢迎的

编辑2:
总之,添加DB_CLOSE_DELAY=-1就成功了。我只是忘了告诉Hibernate生成DDL

这似乎是由于数据库关闭时关闭了连接 初始化,这将导致数据库关闭

因此,当您执行一个单独的SQL查询时,由于数据库已关闭,您将无法找到表:Table EMPLOYER not found

如果要使数据库保持打开状态以供使用,可以尝试添加 数据库URL@Value${spring.datasource.URL}的参数

例如:

jdbc:h2:tcp://localhost/xxxxx:xxxxxx;DB_CLOSE_DELAY=-1
这似乎是由于数据库关闭时关闭了连接 初始化,这将导致数据库关闭

因此,当您执行一个单独的SQL查询时,由于数据库已关闭,您将无法找到表:Table EMPLOYER not found

如果要使数据库保持打开状态以供使用,可以尝试添加 数据库URL@Value${spring.datasource.URL}的参数

例如:

jdbc:h2:tcp://localhost/xxxxx:xxxxxx;DB_CLOSE_DELAY=-1

您使用的是什么版本的h2?另外,为集成测试配置的spring.datasource.url是什么?对不起,我应该显示我的database.properties文件。我把它添加到我的帖子里。这是我的数据库url:jdbc:h2:mem:test,正如我在帖子中添加的,我还尝试了一些参数,比如DB\u CLOSE\u DELAY=-1或DB\u CLOSE\u ON\u EXIT=FALSE。但是没有一个成功。我的h2版本是1.4.187还是不知道-p您使用的是什么版本的h2?另外,为集成测试配置的spring.datasource.url是什么?对不起,我应该显示我的database.properties文件。我把它添加到我的帖子里。这是我的数据库url:jdbc:h2:mem:test,正如我在帖子中添加的,我还尝试了一些参数,比如DB\u CLOSE\u DELAY=-1或DB\u CLOSE\u ON\u EXIT=FALSE。但是没有一个成功。我的h2版本是1.4.187还是不知道-PI编辑了我的帖子,给出了更多的解释。我已经尝试了DB_CLOSE_DELAY=-1和DB_CLOSE_ON_EXIT=FALSE,但没有一个成功:-/仍然不知道?:-pinfine,加上DB_CLOSE_DELAY=-1就成功了。我只是忘了告诉Hibernate生成DDL。我编辑了我的帖子,给出了更多的解释。我已经尝试了DB_CLOSE_DELAY=-1和DB_CLOSE_ON_EXIT=FALSE,但没有一个成功:-/仍然不知道?:-pinfine,加上DB_CLOSE_DELAY=-1就成功了。我只是忘了告诉Hibernate生成DDL。
jdbc:h2:tcp://localhost/xxxxx:xxxxxx;DB_CLOSE_DELAY=-1