hibernate Spring Batch“无效的对象名称Batch_JOB_INSTANCE”

huus2vyu  于 2022-11-14  发布在  Spring
关注(0)|答案(3)|浏览(193)

我已经创建了一个Spring批处理来查询Azure SQL服务器数据库并将数据写入CSV文件。我没有该数据库的create权限。我在运行批处理时收到此错误Invalid Object name BATCH_JOB_INSTANCE。我不希望在主数据库中创建 Spring 批次元数据表。或者,如果我可以将它们放在另一个本地或内存中的数据库(如h2db)中,这将是有帮助的。我也已经添加了spring-batch-initialize-schema=never,这是在这里对类似问题的大多数答案的情况,但这并没有帮助。

编辑:

我解决了Invalid Object name错误,方法是通过扩展DefaultBatchConfigurer类并覆盖setDataSource方法,从而防止在主数据库中创建元数据表,从而在内存Map存储库中创建它们。现在我想尝试两种选择:
1.如何在本地数据库或像h2db这样的内存数据库中创建元数据表。
1.或者,如果我已经在主数据库中创建了元数据表,则元数据表与我从中提取的主表使用不同的模式。如何将我的作业指向另一个模式中的元数据表,以在其中存储作业和步骤详细信息数据。

@Configuration
public class SpringBatchConfig extends DefaultBatchConfigurer{

@Override
    public void setDataSource(DataSource datasource) {

    }
...

我的应用程序.properties文件如下所示:

spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver

spring-batch-initialize-schema=never
spring.batch.job.enabled=false

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
0dxa2lsx

0dxa2lsx1#

我已经创建了一个带有两个数据源的演示。批处理元数据将存储在H2 DB中,作业数据源为Azure SQL。
项目结构如下:

1.我们需要为DataSource Bean定义一个DataSourceConfig类,并使用@Primary注解:

@Configuration
public class DataSourceConfig {

    @Bean(name = "mssqlDataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource appDataSource(){
        return DataSourceBuilder.create().build();
    }
    
    @Bean(name = "h2DataSource")
    @Primary
    // @ConfigurationProperties(prefix="spring.datasource.h2")
    public DataSource h2DataSource() {
        return DataSourceBuilder.create()
                .url("jdbc:h2:mem:thing:H2;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE")
                .driverClassName("org.h2.Driver")
                .username("sa")
                .password("")                   
                .build();
    }
    
}

1.在ItemReaderDbDemo类中,我们使用@Autowired @Qualifier("mssqlDataSource")来指定Spring批处理任务中的数据源:

@Configuration
public class ItemReaderDbDemo {
    
    //generate task Object
    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    
    //Step exec tasks
    //generate step Object
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Autowired
    @Qualifier("mssqlDataSource")
    private DataSource dataSource;

    @Autowired
    @Qualifier("dbJdbcWriter")
    private ItemWriter<? super Todo> dbJdbcWriter;
    
    @Bean
    public Job itemReaderDbDemoJob() {
        return jobBuilderFactory.get("itemReaderDbDemoJob").start(itemReaderDbStep()).build();
    }

    @Bean
    public Step itemReaderDbStep() {
        return stepBuilderFactory.get("itemReaderDbStep")
                .<Todo,Todo>chunk(2)
                .reader(dbJdbcReader())
                .writer(dbJdbcWriter)
                .build();
    }

    @Bean
    @StepScope
    public JdbcPagingItemReader<Todo> dbJdbcReader() {
        JdbcPagingItemReader<Todo> reader = new JdbcPagingItemReader<Todo>();
        reader.setDataSource(dataSource);
        reader.setFetchSize(2);
        reader.setRowMapper(new  RowMapper<Todo>() {
            @Override
            public Todo mapRow(ResultSet rs, int rowNum) throws SQLException {
                Todo todo = new Todo();
                todo.setId(rs.getLong(1));
                todo.setDescription(rs.getString(2));
                todo.setDetails(rs.getString(3));
                return todo;
            }   
            
        });
        SqlServerPagingQueryProvider provider = new  SqlServerPagingQueryProvider();
        provider.setSelectClause("id,description,details");
        provider.setFromClause("from dbo.todo");
        
        //sort
        Map<String,Order> sort = new HashMap<>(1);
        sort.put("id", Order.DESCENDING);
        provider.setSortKeys(sort);
        
        reader.setQueryProvider(provider);
        return reader;
    }
}

1.这是我的应用程序。属性:

logging.level.org.springframework.jdbc.core=DEBUG

spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.jdbcUrl=jdbc:sqlserver://josephserver2.database.windows.net:1433;database=<Your-Database-Name>;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;
spring.datasource.username=<Your-UserName>
spring.datasource.password=<Your-Password>
spring.datasource.initialization-mode=always

1.从我的Azure SQL返回预期结果。顺便说一句,我的Azure SQL用户名没有数据库的创建权限。
结果表明:

omhiaaxx

omhiaaxx2#

如何在本地数据库或像h2db这样的内存数据库中创建元数据表。
为此,您可以使用spring.batch.initialize-schema=embedded
或者,如果我已经在主数据库中创建了元数据表,则元数据表与我从中提取的主表使用不同的模式。如何将我的作业指向另一个模式中的元数据表,以在其中存储作业和步骤详细信息数据。
Spring Batch针对的是数据源,而不是特定的模式。如果元数据表位于不同的模式中,则需要创建指向该模式的第二个数据源,并将其设置在作业存储库中。

zfciruhq

zfciruhq3#

我知道这篇文章有点老了,但我想更新一下。对于较新版本的Spring Boot,不建议使用spring.Batch.初始化模式。我使用的是Spring Boot 2.7.1,较新的属性是spring.Batch.jdbc.Initialize-SCHEMA。在我的例子中:当我收到错误消息时,是因为用户没有CREATE TABLE权限来创建相应的Spring bacth表。添加权限可解决此问题。

相关问题