簡體   English   中英

Spring 批次“無效的 object 名稱 BATCH_JOB_INSTANCE”

[英]Spring Batch "Invalid object name BATCH_JOB_INSTANCE"

我創建了一個 spring 批處理來查詢一個 Azure SQLZ 服務器數據庫並將數據寫入 ZA49CC8D68C5AE761 文件。 我沒有create數據庫的權限。 我在運行批處理時收到此錯誤Invalid Object name BATCH_JOB_INSTANCE 我不希望在主數據庫中創建 spring 批處理元數據表。 或者,如果我可以將它們放在另一個本地或內存數據庫(如 h2db)中,那將會很有幫助。 我還添加了spring-batch-initialize-schema=never ,對於類似問題的大多數答案都是如此,但這並沒有幫助。

編輯:

我通過擴展DefaultBatchConfigurer Class 並覆蓋setDataSource方法來防止將元數據表創建到主數據庫中,從而解決了Invalid Object name錯誤,從而使它們在內存中的映射存儲庫中創建。 現在我想嘗試兩種選擇:

  1. 如何在本地數據庫或內存數據庫(如 h2db)中創建元數據表。
  2. 或者,如果我已經在主數據庫中創建了元數據表,則使用與我從中獲取的主表不同的模式。 如何將我的工作指向另一個模式中的那些元數據表,以在其中存儲工作和步驟詳細信息數據。
@Configuration
public class SpringBatchConfig extends DefaultBatchConfigurer{

@Override
    public void setDataSource(DataSource datasource) {

    }
...

我的 application.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

我創建了一個帶有兩個數據源的演示。 批處理元數據將存放在 H2 DB 中,作業數據源是 Azure SQL。

這是項目結構:

在此處輸入圖片說明

  1. 我們需要定義一個DataSourceConfig類並為 DataSource bean 使用@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 Batch任務中的dataSource:
@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. 這是我的 application.properties:
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 用戶名沒有數據庫的創建權限。
    結果顯示: 在此處輸入圖片說明

如何在本地數據庫或內存數據庫(如 h2db)中創建元數據表。

您可以使用spring.batch.initialize-schema=embedded

或者,如果我已經在主數據庫中創建了元數據表,則在與我從中獲取的主表不同的架構中。 如何將我的工作指向另一個模式中的那些元數據表,以在其中存儲工作和步驟詳細信息數據。

spring 批處理適用於數據源,而不是特定模式。 如果元數據表位於不同的模式中,那么您需要創建指向該模式的第二個數據源並將其設置在作業存儲庫中。

我知道這篇文章有點舊,但我想更新一下。 對於較新版本的 Spring 引導 spring.batch.initialize-schema 已棄用。 我正在使用 Spring Boot 2.7.1 和較新的屬性是spring.batch.jdbc.initialize-schema 在我的情況下:當我收到錯誤消息時,由於用戶沒有創建相應的 spring bacth 表的CREATE TABLE 權限 添加權限可以解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2025 STACKOOM.COM