SequenceInformation missing - jpa

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

Related

How can I connect to an h2 database via odbc / postgres driver where one table contains blob fields?

I'm trying to access an h2 database via odbc. The database itself is running with h2 in server mode. Later on, I try to create an odbc datasource with the postgres unicode sql driver (psqlodbc). If I test my connection with a valid username an password, the h2 console reports an exception and the server process is killed.
Is there another way or parameter to allow the connection via odbc? I tried to append ;MODE=PostgreSQL to the database name but it didn't help.
The following exception is shown (field names and ip addresses removed):
CP server running at tcp://...:9092 (only local connections)
PG server running at pg://...:5435 (only local connections)
Web Console server running at http://...:8082 (only local connections)
org.h2.jdbc.JdbcSQLNonTransientException: Unbekannter Datentyp: "BLOB"
Unknown data type: "BLOB"; SQL statement:
CREATE CACHED TABLE "..."."...."(
"ID" VARCHAR(40) NOT NULL, ..
"SOME_DATA" BLOB, ...
) [50004-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:505)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
at org.h2.message.DbException.get(DbException.java:205)
at org.h2.message.DbException.get(DbException.java:181)
at org.h2.command.Parser.parseColumnWithType(Parser.java:5971)
at org.h2.command.Parser.parseColumnForTable(Parser.java:5697)
at org.h2.command.Parser.parseTableColumnDefinition(Parser.java:8442)
at org.h2.command.Parser.parseCreateTable(Parser.java:8379)
at org.h2.command.Parser.parseCreate(Parser.java:6276)
at org.h2.command.Parser.parsePrepared(Parser.java:903)
at org.h2.command.Parser.parse(Parser.java:843)
at org.h2.command.Parser.parse(Parser.java:815)
at org.h2.command.Parser.prepare(Parser.java:722)
at org.h2.engine.Session.prepare(Session.java:622)
at org.h2.engine.Session.prepare(Session.java:606)
at org.h2.engine.MetaRecord.execute(MetaRecord.java:58)
at org.h2.engine.Database.open(Database.java:759)
at org.h2.engine.Database.openDatabase(Database.java:307)
at org.h2.engine.Database.<init>(Database.java:301)
at org.h2.engine.Engine.openSession(Engine.java:74)
at org.h2.engine.Engine.openSession(Engine.java:192)
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:171)
at org.h2.engine.Engine.createSession(Engine.java:166)
at org.h2.engine.Engine.createSession(Engine.java:29)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:340)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:173)
at org.h2.server.pg.PgServerThread.process(PgServerThread.java:235)
at org.h2.server.pg.PgServerThread.run(PgServerThread.java:101)
at java.lang.Thread.run(Unknown Source)
I experienced the same problem.
I had a test application properties with wrong dialect:
spring:
jpa:
database-platform: org.hibernate.dialect.H2Dialect
open-in-view: false
hibernate:
ddl-auto: create-drop
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect
default_schema: schema
I changed in this way. Everything is working fine.
spring:
jpa:
database-platform: org.hibernate.dialect.PostgreSQL10Dialect
open-in-view: false
hibernate:
ddl-auto: create-drop
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQL10Dialect
default_schema: schema
To check database version I used:
select version();

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

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.

Grails 3.3.x does not seem to support schema-per-tenant with PostgreSQL

Has anybody managed to use Grails 3.3.x with multi-tenancy and PostgreSQL? The problem appears to be with the SQL syntax used in DefaultSchemaHandler.groovy class. For PostgreSQL the correct syntax is: SET SCHEMA 'schemaName' but DefaultSchemaHandler omits the single ticks: SET SCHEMA schemaName which causes the startup to fail with:
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "information_schema"
Further exceptions list other schema's in the PG DB until startup fails completely. There doesn't seem to be any way to override DefaultSchemaHandler, nor anybody else battling with this issue, which surprises me.
I should add that this all works fine in Grails 3.2.11 which I was busy porting from.
I solved my own problem by implementing my own SchemaHandler as follows:
#CompileStatic
#Slf4j
class PostgreSQLSchemaHandler extends DefaultSchemaHandler {
PostgreSQLSchemaHandler() {
super("SET SCHEMA '%s'", "CREATE SCHEMA '%s'", "public")
}
}
And then in application.yml I added schemaHandler as follows:
dataSource:
pooled: true
jmxExport: true
driverClassName: org.postgresql.Driver
dialect: org.hibernate.dialect.PostgreSQLDialect
schemaHandler: com.mypackage.PostgreSQLSchemaHandler

Hibernate fail to register REF_CURSOR parameter

I am new to Hibernate. Using the 5.2.10 FINAL version connecting to Oracle 11g using the Oracle10gDialect with JPA 2.1 and ojdbc8.jar
I try to access a simple stored procedure taking a String input parameter and output a Oracle SYS_REFCURSOR.
StoredProcedureQuery call = session.createStoredProcedureCall("sp_get_profile");
call.registerStoredProcedureParameter(1, String.class, ParameterMode.IN);
call.registerStoredProcedureParameter(2, Class.class, ParameterMode.REF_CURSOR);
call.execute();
An exception occur when I access the function
ERROR SqlExceptionHelper Invalid column type: 2012
DatabaseException::error=[Error registering REF_CURSOR parameter [2]]
I try to write a simple program connecting to DB with the Oracle Driver only. I will have the same error if I register Types.REF_CUSOR as the output parameter to CallableStatement.
cs.registerOutParameter(2, Types.REF_CURSOR);
And the problem can be solved by changing to OracleTypes
cs.registerOutParameter(2, OracleTypes.CURSOR);
Anyone know what is wrong? I need to fall back to use the traditional SQL programming if I cannot get the stored procedure access success. . . please help.
Finally got it work, I should check the Oracle JDBC document first before implementation.
ojdbc8 should be good for Oracle 12c + JDK8 + JPA2.1 with Oracle12cDialect.
For Oracle 11g, need to use ojdbc6.jar
I solved that issue by debugging OJDBC and Hibernate, the building from sources a patched Hibernate CORE library (5.4.15-Final).
I have patched the method ExtractedDatabaseMetaDataImpl.supportsRefCursors which returns always false.

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