java - Spring Batch - 在 Eclipse 中作为应用程序运行 - SQLException 无效的模式名称 - JUnit

标签 java eclipse junit spring-batch sqlexception

我是Spring的新手,谢谢你的帮助
我的 JUnit 测试类运行良好:

import java.sql.SQLException;
import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import junit.framework.TestCase;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/Spring-Test-Context.xml")
@Configuration
@EnableAutoConfiguration

public class TestConnexionJdbc extends TestCase {

    /*@Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/my_database");
        dataSource.setUsername("my_cnx_role");
        dataSource.setPassword("my_password");
        return dataSource;
    }*/

    @Autowired
    private DataSource dataSource;

    private TaskletTruncateDonnees tasklet;



    @Test
    public void testTaskletInstanciation() throws Exception {

        assertNotNull("datasource is not null OK",this.dataSource);
        this.tasklet  = new TaskletTruncateDonnees(this.dataSource);
        assertNotNull("tasklet is not null OK",this.tasklet);
        assertEquals("tasklet dataSource username OK",this.tasklet.getDataSourceUsername(), "my_cnx_role");

    }

    @Test
    public void testTaskletTruncate() throws SQLException {
        assertNotNull("datasource is not null OK",this.dataSource);
        this.tasklet  = new TaskletTruncateDonnees(this.dataSource);
        assertNotNull("tasklet is not null OK",this.tasklet);
        this.tasklet.truncateDonnees();
    }

}

所以我尝试用 Eclipse 运行类似的 Spring-Batch > 作为应用程序运行 :首先是启动器:

import org.springframework.boot.SpringApplication;

public class Main {

    public static void main(String [] args) {
        System.exit(SpringApplication.exit(SpringApplication.run(BatchConfiguration.class, args)));
    }
}

和批处理:

@ContextConfiguration("/Spring-Batch-Context.xml")
@Configuration
@EnableBatchProcessing
@EnableAutoConfiguration
public class BatchConfiguration {

    private long initMillis;

    /*@Bean
    public static DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/my_database");
        dataSource.setUsername("my_cnx_role");
        dataSource.setPassword("my_password");
        System.out.println("bean dataSource =");
        System.out.println(dataSource);
        return dataSource;
    }*/


    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Autowired
    private DataSource dataSource;

    private TaskletTruncateDonnees taskletTruncate;

    //tag::readerwriterprocessor[]

    @Bean
    public ItemReader<Donnee> reader() {

        Collection<Donnee> collection = new ArrayList<Donnee>();

        for(int i=0;i<1000;i++) {
            Donnee donnee = new Donnee();
            donnee.setNum_ligne(i);
            donnee.setPrenom("Johnny_"+i);
            donnee.setNom("Roll_over_The_Mountain_"+i);
            donnee.setRue(i+" Main Avenue");
            donnee.setVille("Los Angeles District num "+i);
            donnee.setEtat("La_californie_"+i);
            collection.add(donnee);
        }

        ItemReader<Donnee> reader = new IteratorItemReader<Donnee>(collection);

        return reader;
    }


    @Bean
    public ItemProcessor<Donnee, Donnee> processor() {
        return new DonneeItemProcessor();
    }

    @Bean
    public ItemWriter<Donnee> writer(DataSource dataSource) {

        long deltaMillis = System.currentTimeMillis()-this.initMillis;

        JdbcBatchItemWriter<Donnee> writer = new JdbcBatchItemWriter<Donnee>();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Donnee>());
        writer.setSql("insert into schema_batch_01.table_batch_donnees_massives values (:num_ligne,"+deltaMillis+",:prenom, :nom, :rue, :ville, :etat)");
        writer.setDataSource(dataSource);
        return writer;
    }
    // end::readerwriterprocessor[]


    @Bean
    public ItemWriter<Donnee> truncater(DataSource dataSource) {

        long deltaMillis = System.currentTimeMillis()-this.initMillis;

        JdbcBatchItemWriter<Donnee> writer = new JdbcBatchItemWriter<Donnee>();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Donnee>());
        writer.setSql("insert into schema_batch_01.table_batch_donnees_massives values (:num_ligne,"+deltaMillis+",:prenom, :nom, :rue, :ville, :etat)");
        writer.setDataSource(dataSource);
        return writer;
    }

    @Bean
    public Job job(Step taskletTruncate,Step stepInserts) {

        this.initMillis = System.currentTimeMillis();

        Job job = jobBuilderFactory.get("job1")
                .incrementer(new RunIdIncrementer())
                .start(taskletTruncate).next(stepInserts)
                .build();

        return job;
    }

    @Bean 
    public Step taskletTruncate() {

        this.taskletTruncate = new TaskletTruncateDonnees(this.dataSource);

        return stepBuilderFactory.get("taskletTruncate")
                .tasklet(this.taskletTruncate).build();
    }


    @Bean
    public Step stepInserts(ItemReader<Donnee> reader,ItemWriter<Donnee> writer) {

        Step insertSteps = stepBuilderFactory.get("stepInserts")
                .<Donnee, Donnee> chunk(10)
                .reader(reader)
                .writer(writer)
                .build();

        return insertSteps;
    }
    // end::jobstep[1]

}

问题
当我使用@ContextConfiguration("/Spring-Test-Context.xml") 时,测试有效!!
当我在 BatchConfiguration 中使用 @Bean 时,批处理工作!!
当我使用 @ContextConfiguration("/Spring-Batch-Context.xml") 批处理失败时...
当然xml是一样的
这是 Eclispe 输出:用户名错误,它是 SA,为什么?
用户名对于 JUnit 测试和使用 @Bean 的 Batch 是正确的 ...

2014-07-31 16:28:32.487  INFO 4300 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@786c4ad7: startup date [Thu Jul 31 16:28:32 CEST 2014]; root of context hierarchy
2014-07-31 16:28:33.673  WARN 4300 --- [           main] o.s.c.a.ConfigurationClassEnhancer       : @Bean method ScopeConfiguration.stepScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean Javadoc for complete details
2014-07-31 16:28:33.688  WARN 4300 --- [           main] o.s.c.a.ConfigurationClassEnhancer       : @Bean method ScopeConfiguration.jobScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean Javadoc for complete details
2014-07-31 16:28:33.939  INFO 4300 --- [           main] o.s.j.d.e.EmbeddedDatabaseFactory        : Creating embedded database 'testdb'
2014-07-31 16:28:35.109  INFO 4300 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [org/springframework/batch/core/schema-hsqldb.sql]
2014-07-31 16:28:35.141  INFO 4300 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from class path resource [org/springframework/batch/core/schema-hsqldb.sql] in 32 ms.
2014-07-31 16:28:35.328  INFO 4300 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2014-07-31 16:28:35.360  INFO 4300 --- [           main] o.s.b.a.b.JobLauncherCommandLineRunner   : Running default command line with: []
2014-07-31 16:28:35.375  INFO 4300 --- [           main] o.s.b.c.r.s.JobRepositoryFactoryBean     : No database type set, using meta data indicating: HSQL
2014-07-31 16:28:35.547  INFO 4300 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : No TaskExecutor has been set, defaulting to synchronous executor.
2014-07-31 16:28:35.656  INFO 4300 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=job1]] launched with the following parameters: [{run.id=1}]
2014-07-31 16:28:35.687  INFO 4300 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [taskletTruncate]
truncateDonnees DataSource= 
org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory$EmbeddedDataSourceProxy@3b54c1f8
Username=
SA
2014-07-31 16:28:35.718  INFO 4300 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2014-07-31 16:28:35.859  INFO 4300 --- [           main] o.s.jdbc.support.SQLErrorCodesFactory    : SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
2014-07-31 16:28:35.874 ERROR 4300 --- [           main] o.s.batch.core.step.AbstractStep         : Encountered an error executing step taskletTruncate in job job1

org.springframework.jdbc.UncategorizedSQLException: StatementCallback; uncategorized SQLException for SQL [truncate table "schema_batch_01"."table_batch_donnees_massives"]; SQL state [3F000]; error code [-4850]; invalid schema name: schema_batch_01; nested exception is java.sql.SQLException: invalid schema name: schema_batch_01
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)

有什么想法吗?

最佳答案

不要将 @ContextConfiguration 用于您的主要配置文件。它用于集成测试。这就是为什么它在测试 jar 中。参见 the api

@ContextConfiguration defines class-level metadata that is used to determine how to load and configure an ApplicationContext for integration tests.

改为使用 @ImportResource

this annotation provides functionality similar to the element in Spring XML. It is typically used when designing @Configuration classes to be bootstrapped by AnnotationConfigApplicationContext, but where some XML functionality such as namespaces is still necessary.

执行此操作时,您还需要确保没有循环引用,这意味着您在 xml 文件中没有指向 java 配置类的组件扫描。此外,如果您确实有这个,并且需要将其取出,请确保在 java 配置文件中有一个 @ComponentScan,它可以恢复因取出该 xml 而丢失的任何(如果有的话)组件组件扫描。

综上所述,我觉得这可能是您的问题,基于三种情况以及哪种情况失败,哪种情况成功。我在发生相同问题的地方做了一些简单的测试 - 不完全相同,但是没有读取 bean 的问题。

关于java - Spring Batch - 在 Eclipse 中作为应用程序运行 - SQLException 无效的模式名称 - JUnit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25062389/

相关文章:

java - BufferedWriter newLine 方法未找到

java - 使用 Java Stream 将数字字符串解析为 Integer 对象列表

java - 如何为方法参数中具有私有(private)枚举的方法编写 JUnit 测试用例

java - org.springframework.util.Assert 在我的 Surefire 报告中显示为错误,而实际上它应该是失败

java - 编写处理行尾断言的跨平台单元测试

java - 通过为单个线程分配唯一的 ID 来提高输出的清晰度

java - 从 Android json 响应中删除对象

java - 无法解析 Adb 版本(错误的 ELF 类)

java - 从 GWT 项目引用 Eclipse Java 项目

java - 如何将第 3 方 JAR 添加到 Maven 项目