We are using spring-boot with spring-boot-starter-jooq. For some complex checks of constraints triggers are used which raise error with specific message. The exception is caught on persistence layer and converted into business exception.
The behavior has been changed in last spring boot versions 2.4.x. For example hsqldb with scherma:
CREATE TABLE tab1 (
K INT PRIMARY KEY
)^;
CREATE TRIGGER trig1 BEFORE INSERT ON tab1
BEGIN ATOMIC
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'some error';
END^;
and the code for insert into table:
#Transactional
public void withTriggerException() {
create.insertInto(DSL.table("tab1"))
.set(DSL.field("k"), 1)
.execute();
}
The type and the message of thrown exception differs from spring-boot version.
2.3.6, 2.3.9
org.springframework.jdbc.UncategorizedSQLException: jOOQ; uncategorized SQLException for SQL [insert into tab1 (k) values (cast(? as int))]; SQL state [45000]; error code [5800]; some error; nested exception is java.sql.SQLException: some error
2.4.0, 2.4.1, 2.4.2
java.lang.NullPointerException: null
2.4.3
org.jooq.exception.DataAccessException: SQL [insert into tab1 (k) values (?)]; Unspecified RuntimeException
at org.jooq_3.14.7.HSQLDB.debug(Unknown Source) ~[na:na]
at org.jooq.impl.Tools.translate(Tools.java:2892) ~[jooq-3.14.7.jar:na]
at org.jooq.impl.DefaultExecuteContext.exception(DefaultExecuteContext.java:730) ~[jooq-3.14.7.jar:na]
at org.springframework.boot.autoconfigure.jooq.JooqExceptionTranslator.handle(JooqExceptionTranslator.java:83) ~[spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.autoconfigure.jooq.JooqExceptionTranslator.exception(JooqExceptionTranslator.java:55) ~[spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.jooq.impl.ExecuteListeners.exception(ExecuteListeners.java:274) ~[jooq-3.14.7.jar:na]
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:390) ~[jooq-3.14.7.jar:na]
at org.jooq.impl.AbstractDelegatingQuery.execute(AbstractDelegatingQuery.java:119) ~[jooq-3.14.7.jar:na]
at com.example.demo.FooDAO.withTriggerException(DemoApplication.java:38) ~[classes/:na]
...
The behavior has been reproduced on hsqldb but is same on PostgreSQL. Another errors (duplicate key, foreign keys, etc.) are working as expected.
It is possible to obtain error message ("some error" in example) from trigger with spring-boot 2.4.x?
You probably ran into this issue:
https://github.com/jOOQ/jOOQ/issues/11304, which has been fixed in jOOQ 3.14.6 and 3.15.0.
Some background on the incompatible change in Spring that produced this NPE regression in jOOQ can be seen here:
https://github.com/spring-projects/spring-framework/issues/24064
The fix should be available in Spring Boot 2.5.0 and 2.4.3:
https://github.com/spring-projects/spring-boot/issues/25214
https://github.com/spring-projects/spring-boot/issues/25240
You should be able to access the JDBC SQLException from jOOQ's DataAccessException using DataAccessException.getCause(Class), e.g.
exception.getCause(SQLException.class);
But there's probably a better way to have the Spring exception translator provide you with the actual cause directly.
Related
I have configured a spring state machine with JPA config to an H2 Database.
I see the following error at run time
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL not allowed for column "STATEACTIONS_ID"; SQL statement:
insert into state_action (JpaRepositoryState_id, exitActions_id) values (?, ?) [23502-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:508)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
In spring-data-jdbc 2.3.2 with 2.6.4 data-jdbc starter. I am seeing the following output. Not clear if this is my error in a model layer or an issue with the framework.
This happens when the root aggregate tries to get updated because of a one-to-many reference modification.
As far as I can tell the SQL spec expects a SET statement here. This is the exception I am getting :
Caused by: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [UPDATE "tb_entity" WHERE "tb_entity"."field_id" = ?]; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "WHERE"
Position: 21
Any suggestion is welcome.
Take a look at the foreign table primary key. Even though not strictly necessary to be in consistent state. Anyways, one of the statement of 3NF is that all records in a table must be uniquely identified not matter if they don't represent an entity perse. Data-jdbc uses this key for the relations with List, Set, Map.
https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#jdbc.entity-persistence.types
I have an API in spring boot using hibernate.
Initially, the database to request was Hive, it's now Kudu throw Impala.
I followed recommendations and set the dialect to org.hibernate.dialect.HSQLDialect.
The classical requests work fine excepting the Page<T> findAll(#Nullable Specification<T> var1, Pageable var2) from org.springframework.data.jpa.repository
when I paginate (page > 0) and so I have the exception:
[Cloudera]ImpalaJDBCDriver ERROR processing query/statement. Error Code: 0, SQL state: TStatus(statusCode:ERROR_STATUS, sqlState:HY000, errorMessage:ParseException: Syntax error in line 1:
select limit 10 10 qualityres0_.id ...
^
Encountered: LIMIT
Expected: ALL, CASE, CAST, DATE, DEFAULT, DISTINCT, EXISTS, FALSE, IF, INTERVAL, LEFT, NOT, NULL, REPLACE, RIGHT, STRAIGHT_JOIN, TRUNCATE, TRUE, IDENTIFIER
Spring boot version: 2.3.4.RELEASE
Impala jdbc driver: com.cloudera.impala.jdbc ImpalaJDBC41 v2.6.15.1017
Finally it works fine with org.hibernate.dialect.SQLServerDialect
I am using Mybatis with springboot to connect with an Oracle database. In that process I need to update multiple fields in bulk.
I have created a procedure to implement that functionality on the database side. When calling that procedure from the DAO layer, the following exception occurs:
org.springframework.jdbc.UncategorizedSQLException:
Error getting generated key or setting result parameter object.
Cause
Java.sql.SQLException: operation not allowed.
<insert id="update" parameter="java.util.map" statement="callable">
{ call test.bulk_update_procedure(#{customerid, mode=IN , jdbcType= varchar},#{firstname, mode= IN, jdbcType= varchar},#{age,mode=IN, jdbcType=varchar})
</insert>
DBMS - oracle 11gr2
we recently upgraded the IDE and OS of a java console application that runs 10 times a month.
now None of our queries work properly since hibernate converts the letter i to İ which is not I. All insert statements and id fields affected negatively.
now in our queries
id -> İD not ID
insert -> İNSERT not INSERT
neither select statements nor inserts do not execute.
for example:
in the previous version Select id from table a is now sent to the db as
SELECT İD from table a ,
and we dont have such a column called İD at all.
stack trace is as follows
Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "İD": geçersiz belirleyici (invalid identifier)
Query: ReadObjectQuery(name="readObject" referenceClass=OrtakEntity sql="SELECT İD, ADİ, ALACAKLARİNDAHACİZVARMİ, ANNEADİ, FROM A WHERE (İD = ?)")
********************sistem toplam sure***********************0.0
********************Time unit toplam sure***********************0
Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "İD": geçersiz belirleyici
Error Code: 904
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:684)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:526)
at org.eclipse.persistence.internal.session
I resolved the issue by changing the settings of the computer to English and United States as location. (still not the best approach but now the program runs)