Spring Batch / Postgres : ERROR: relation "batch_job_instance" does not exist - postgresql

I am trying to configure Spring Batch to use PostGres DB. I have included the following dependencies in my build.gradle.kts file:
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.postgresql:postgresql")
My application.yml for my SpringBatch module has the following included:
spring:
datasource:
url: jdbc:postgresql://postgres:5432/springbatchdb
username: postgres
password: root
driverClassName: org.postgresql.Driver
docker-compose.yml
postgres:
restart: always
image: postgres:12-alpine
container_name: postgres
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=root
- POSTGRES_DB=springbatchdb
ports:
- "5432:5432"
volumes:
- postgresql:/var/lib/postgresql
- postgresql_data:/var/lib/postgresql/data
However, when I try to add a data file I see the following error in the logs of both my SpringBatch Docker container, and the PostGres container:
Spring Batch:
<<< Exception in method: org.meanwhileinhell.spring.batch.server.SpringBatchController.handle Error Message: PreparedStatementCallback; bad SQL grammar [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]; nested exception is org.postgresql.util.PSQLException: ERROR: relation "batch_job_instance" does not exist
PostGres:
LOG: database system is ready to accept connections
2021-01-08 09:54:56.778 UTC [56] ERROR: relation "batch_job_instance" does not exist at character 39
2021-01-08 09:54:56.778 UTC [56] STATEMENT: SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = $1 and JOB_KEY = $2
2021-01-08 09:55:27.033 UTC [56] ERROR: relation "batch_job_instance" does not exist at character 39
2021-01-08 09:55:27.033 UTC [56] STATEMENT: SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = $1 and JOB_KEY = $2
I can see that the SB server is picking up POSTGRES from my metadata ok.
JobRepositoryFactoryBean : No database type set, using meta data indicating: POSTGRES
What am I missing to get the initial db configured during the server start?
Edit: I've tried adding spring.datasource.initialize=true explicitly, but no change.

Please check below added in application.yml
spring.batch.initialize-schema: always
Please check below dependencies are added
<artifactId>spring-boot-starter-batch</artifactId>

yaml file is
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=1234
spring.datasource.driver-class-name=org.postgresql.Driver
spring.batch.jdbc.initialize-schema=always
gradle dependencies
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-batch'
implementation 'org.projectlombok:lombok-maven-plugin:1.18.6.0'
implementation group: 'org.postgresql', name: 'postgresql', version: '42.3.1'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.batch:spring-batch-test'
}

You need to set spring.batch.initialize-schema=always property to tell Spring Boot to create Spring Batch tables automatically. Please refer to the Initialize a Spring Batch Database section of Spring Boot's reference documentation for more details.

For anyone who has spring.batch.initialize-schema=always set already and it's still not working, also verify that you are connecting to the database with a user that has sufficient privileges, including to create the necessary tables.

in application.properties,
Prior Spring Boot 2.5 we can use
spring.batch.initialize-schema=ALWAYS
Later version of Spring Boot 2.5 use below
spring.batch.jdbc.initialize-schema=ALWAYS

Solution that worked for me in Spring 5.0!
I spent a lot of time resolving issues like ERROR: relation "X" does not exist when using the latest Spring Boot Starter 3.0 and Spring Batch 5.0.
spring.batch.jdbc.initialize-schema=always
However, it didn't create the necessary tables for me. Though as per the documentation, it should have created tables.
After a lot of research, I found, that in the latest Spring Batch 5.0, there are a lot of improvements. And I was doing a lot of things wrong when migrating to the new Spring 5.
Remove #EnableBatchProcessing from your configurations. As you don't need that anymore with the latest Spring Batch 5.
Example:
#Configuration
#AllArgsConstructor
#EnableBatchProcessing //please remove it.
public class SpringBatchConfiguration {}
change it to:
#Configuration
#AllArgsConstructor
public class SpringBatchConfiguration {}
PlatformTransaction Manager: The second thing I was doing wrong was using an incorrect Transaction Manager, if you are using JPA for persisting entities you need a corresponding Transaction Manager.
I was using the ResourcelessTransactionManager() which was wrong in my case and was creating a lot of headaches while running.
For JPA you need a JpaTransactionManager()
Something like:
#Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
The third thing I learned after mistakes; we don't need to create a bean of Datasource unless we are doing something complex like having 2 Datasource one for writing Spring Batch associated tables and another for persisting our business data.
Wherever we are required to use JobRepository just inject it.
Something like:
#Bean
#Autowired
Job job(JobRepository jobRepository) {
JobBuilder jobBuilderFactory = new JobBuilder("somename", jobRepository );
return jobBuilderFactory.flow(step1(jobRepository)).end()
.build();
}
For more details on migrations: Spring Migration 3 Guide.

Related

Quarkus + Hibernate + h2 - cannot create id

I'm using quarkus application with Postgres DB. For testing, I'm using h2 in-memory DB.
When I upgraded the version of hibernate to 5.6 I started facing issues with h2 tests. I found spring developers recommending hibernate.id.new_generator_mappings=false or set
#GeneratedValue(strategy = GenerationType.IDENTITY). The first thing does nothing if I put it in application.properties. The second thing helps for testing but now the application cannot generate an id (error like: cannot save id null).
When running tests:
Error executing DDL "create sequence hibernate_sequence start 1 increment 1" via JDBC Statement: org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create sequence hibernate_sequence start 1 increment 1" via JDBC Statement
h2 configured as documented in quarkus.
%in-memory-profile.quarkus.datasource.db-kind = h2
%in-memory-profile.quarkus.datasource.jdbc.url = jdbc:h2:mem:test
It worked before upgrading quarkus and hibernate.

How to fix the DB calls exception - ERROR: Cannot execute INSERT in a read-only transaction in Spring boot JPA

I am facing the below error when doing insert/updates/deletes using Spring Boot -JPA
when executing the Postgres calls?
org.springframework.orm.jpa.JpaSystemException : could not execute statement ; nested exception is org.hibernate.exception.GenereircJDBCException : Could not execute statement with root cause org.postgreql.util.PSQLException: ERROR cannot execute INSERT in a read-only transaction
The application is kind of modeled along the lines as in
https://springframework.guru/how-to-configure-multiple-data-sources-in-a-spring-boot-application/
I am using the below stack
Spring boot - 2.2.7.RELEASE
JPA 2.0
This is a multidatasource application and i can't make any changes at the DB server.
Are there any changes that we can do at the java code end to fix the issue.
Regards

SequenceInformation missing

I'm working with a Spring boot Application connecting to an AS400 Database using the com.ibm.db2.jcc.DB2Driver driver with Spring Data JPA.
I use the org.hibernate.dialect.DB2Dialect dialect.
When I start the Application, I get the Error
Could not fetch the SequenceInformation from the database
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=SYSCAT.SEQUENCES;TABLE, DRIVER=4.26.14
Meaning the Table SYSCAT.SEQUENCES is missing, which it is, because it's not needed.
The Application works fine, but the error bothers me.
As far as I see, SequenceInformations are only important when I generate an ID somewhere, what I don't do.
This Application is only used to copy data from one place to another, so I only use JPAs #Id annotation but not the #GeneratedValue one.
Am I missing some use for the SequenceInformation?
Is there some way to turn off the fetching of SequenceInformation?
Those are my application properties:
spring:
datasource:
driver-class-name: com.ibm.db2.jcc.DB2Driver
hikari.connection-test-query: values 1
hikari.maximum-pool-size: 25
jpa:
database-platform: DB2Platform
hibernate.ddl-auto: none
open-in-view: false
properties:
hibernate:
dll-auto: none
dialect: org.hibernate.dialect.DB2Dialect
naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
You use the wrong dialect. Please use:
org.hibernate.dialect.DB2400Dialect
I have changed dialect from DB2Dialect to DB2400Dialect and it worked for me.
##spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.DB2Dialect
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.DB2400Dialect

Spring Boot JPA Schema Initialization

I want to initialise my datasource with a DLL script in my spring boot project (only during dev of course). As mentioned in the docs here I set the spring.datasource.schema property to the DLL scripts which is in src/main/resources/postgresql/define-schema.sql.
spring:
profiles: dev
datasource:
platform: postgresql
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/postgres
username: postgres
password: ****
initialize: true
schema: ./postgresql/define-schema.sql
continue-on-error: false
jpa:
hibernate:
ddl-auto: validate
generate-ddl: false
show-sql: true
But the script won't be executed. I also tried to put it on the class path root and call it schema.sql ... Nothing happens.
The dev profile is selected, at least I see it in the log: The following profiles are active: dev
The application than fails on the JPA schema validation.
The only warning I get from hibernate:
Found use of deprecated [org.hibernate.id.SequenceGenerator] sequence-based id generator; use org.hibernate.id.enhanced.SequenceStyleGenerator instead. See Hibernate Domain Model Mapping Guide for details.
But I don't think this has any to do with the initialise problem.
I've got spring-boot-security-starter in my dependencies but not configured yet, could that be a problem source?
Does anybody recognise an obivous typo, mistake anything else?
Looking forward hearing from you!
Amp
Prefix the path to your sql script with classpath
Example:
spring.datasource.schema=classpath:/postgresql/define-schema.sql

Spring data configuration for mongodb

I am using spring data for storing and fetching records from the database. Initially the database was MySQL, but now I want to configure the same application for mongodb. Please the application resource properties for MysQL.
# ===============================
# = DATA SOURCE
# ===============================
# Connection url for the database connection
spring.datasource.url = jdbc:mysql://localhost:27017/purchase_books
# Username and password
spring.datasource.username = root
spring.datasource.password = root
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
# ===============================
# = JPA / HIBERNATE
# ===============================
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update): with "update" the database
# schema will be automatically updated accordingly to java entities found in the project
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# Allows Hibernate to generate SQL optimized for a particular DBMS
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
Can anyone please tell the configuration changes in case of mongodb ?
MySQL is an RDBMS and MongoDB is an Document Database.
Hibernate supports NOSQL Database in the form OGM (Object/Grid Mapper), Documentation on OGM http://docs.jboss.org/hibernate/ogm/4.2/reference/en-US/html/
Refer the below example for Spring, Hibernate and MongoDB
https://pragmaticintegrator.wordpress.com/2011/07/14/use-spring-and-hibernate-with-mongodb/
Moreover if you are using spring and if you want to remove Hibernate you can go for Spring MongoTemplate
Refer the sample in the below url
https://spring.io/guides/gs/accessing-data-mongodb/
spring.data.mongodb.uri=mongodb://localhost:27017/<database name>
spring.datasource.username= <username>
spring.datasource.password= <password>
#OR
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=<database name>
spring.data.mongodb.username=<username>
spring.data.mongodb.password=<password>