Persist Error while saving spring state machine - spring-statemachine

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)

Related

Unexpected mapping of exception from trigger - spring-boot 2.4.x + jOOQ

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.

JPA error in merge: Password expired error if insert only

We are using entitymanager merge method to either update (if existing) or insert (if not existing) records in a certain table. What happens is if it is an update, there are no errors, but if it is insert, we see the following error from our logs:
Caused by: java.sql.SQLException: ORA-28001: the password has expired\n DSRA0010E: SQL State = 99999, Error Code = 28,001\n\tat oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)\n\tat oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:392)\n\tat oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:385)\n\tat oracle.jdbc.driver.T4CTTIfun.processError(T4CTTIfun.java:938)\n\tat oracle.jdbc.driver.T4CTTIoauthenticate.processError(T4CTTIoauthenticate.java:480)\n\tat oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:655
When we checked the datasource if connection successful - we get no password expired error.
We also tried manual insert to the table via oracle sql developer tool - no error
Can anyone advise why this is happening?

hibernate generated sql query changes characters improperly

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)

table does not exist error during execution on powercenter workflow

During execution of workflow, I am getting below error while inserting the data in the table (TARGET), whereas when I am connecting same database user then I am able to insert the data, but powercenter is throwing the below error.
I have already created the synonym as well as given all the access.
Severity Timestamp Node Thread Message Code Message
ERROR 23/05/2015 20:55:59 node01_CSADevelopment WRITER_1_*_1 WRT_8229 Database errors occurred:
ORA-00604: error occurred at recursive SQL level 1
ORA-00942: table or view does not exist
Database driver error...
Function Name : Prepare DPL
SQL Stmt : INSERT INTO TARGET(ID,NAME) VALUES ( ?, ?)
Oracle Fatal Error
Database driver error...
Function Name : Execute Multiple
SQL Stmt : INSERT INTO TARGET(ID,NAME) VALUES ( ?, ?)
Oracle Fatal Error
Please assist.
someone is running or finished running a DDL statement on the table and have not committed. Identify that oracle session and kill it or you can commit that transaction or wait until the timeout expires on that table.

Hibernate Persist for large field values gives ConstraintViolationException

I am facing an issue with persisting records for an Entity(YieldCurveArchive) with a field (reason) having a length equivalent to 2048 characters. Following are the scenarios and their results:
Upload new Entity with smaller reason fields: Works fine.
Upload Entity with reason fields
changed with larger (2048 characters) data set: Works fine. Again as
above. This is an update of the existing records.
Upload new Entity
with larger (2048 characters) reason fields: Fails.
I have also tried flushing the hibernate query buffer using entityManager.flush() but the above test results do not change.
I suspect there could be an issue with the buffering that Hibernate performs before actually doing a final insert into database:
Selection of the available records in database to compare with
existing dataset.
Insert being fired but only kept in the buffer of
hibernate to fire a bulk update.
Another select being fired for a
different client. Upon seeing another select, hibernate decides to
fire the insert into the database and then fails.
An excerpt of the trace from the failed logs:
2013-07-02 12:46:00,792 WARN [pool-1-thread-4]: org.hibernate.util.JDBCExceptionReporter - SQL Error: 1400, SQLState: 23000
2013-07-02 12:46:00,792 ERROR [pool-1-thread-4]: org.hibernate.util.JDBCExceptionReporter - ORA-01400: cannot insert NULL into ("CORE_TOTEM"."YC_MONTHLY_ARCHIVE"."PKEY")
2013-07-02 12:46:00,792 WARN [pool-1-thread-4]: org.hibernate.util.JDBCExceptionReporter - SQL Error: 1400, SQLState: 23000
2013-07-02 12:46:00,792 ERROR [pool-1-thread-4]: org.hibernate.util.JDBCExceptionReporter - ORA-01400: cannot insert NULL into ("CORE_TOTEM"."YC_MONTHLY_ARCHIVE"."PKEY")
2013-07-02 12:46:00,985 ERROR [pool-1-thread-4]: org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:64)
at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:996)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1141)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:65)
at markit.totem.dao.DaoHelper.list(DaoHelper.java:19)
at com.markit.totem.rates.yieldcurve.dao.YieldCurveArchiveDao.getArchivesMonthly(YieldCurveArchiveDao.java:172)
at com.markit.totem.rates.yieldcurve.dao.YieldCurveArchiveDao$$FastClassByCGLIB$$55ef1569.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:628)
at com.markit.totem.rates.yieldcurve.dao.YieldCurveMonthlyArchiveDao$$EnhancerByCGLIB$$6aa04fe7.getArchivesMonthly(<generated>)
at com.markit.totem.rates.yieldcurve.results.upload.monthly.YieldCurveMonthlyArchivePersister.getExisting(YieldCurveMonthlyArchivePersister.java:38)
at com.markit.totem.rates.yieldcurve.results.upload.YieldCurveArchivePersister.persist(YieldCurveArchivePersister.java:68)
at com.markit.totem.rates.yieldcurve.results.upload.YieldCurveArchivePersister$$FastClassByCGLIB$$ac0db3fb.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:628)
at com.markit.totem.rates.yieldcurve.results.upload.monthly.YieldCurveMonthlyArchivePersister$$EnhancerByCGLIB$$4b00cfa0.persist(<generated>)
at com.markit.totem.rates.yieldcurve.results.upload.YieldCurveResultsUploader.upload(YieldCurveResultsUploader.java:158)
at com.markit.totem.rates.yieldcurve.results.upload.YieldCurveResultsUploadTask.run(YieldCurveResultsUploadTask.java:53)
at com.markit.totem.workflow.WorkflowExecutor.executeWorkflowTask(WorkflowExecutor.java:258)
at com.markit.totem.workflow.WorkflowExecutor.executeSubWorkflow(WorkflowExecutor.java:227)
at com.markit.totem.workflow.WorkflowExecutor.access$000(WorkflowExecutor.java:17)
at com.markit.totem.workflow.WorkflowExecutor$1.run(WorkflowExecutor.java:72)
at markit.totem.dao.Transactionator.execute(Transactionator.java:19)
at markit.totem.dao.Transactionator$$FastClassByCGLIB$$c9204755.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
at markit.totem.dao.Transactionator$$EnhancerByCGLIB$$4eec78e2.execute(<generated>)
at com.markit.totem.workflow.WorkflowExecutor.execute(WorkflowExecutor.java:83)
at com.markit.totem.workflow.WorkflowExecutor.execute(WorkflowExecutor.java:213)
at com.markit.totem.workflow.WorkflowManager$OldWorkflow.execute(WorkflowManager.java:218)
at com.markit.totem.workflow.WorkflowManager$1.run(WorkflowManager.java:119)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("CORE_TOTEM"."YC_MONTHLY_ARCHIVE"."PKEY")
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:367)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:9055)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
My initial thoughts were that it fails due to the encoding difference in database and default encoding from Hibernate.
Like underlying database uses Oracle and the NLS_CHARACTERSET is defined as:
NLS_CHARACTERSET AL32UTF8
Hence it stores, 1 character as 4 bytes and any special character as 6 bytes. My insert into the Oracle fails for 1001 but passes till i insert 1000 characters. However, if I do an update with more characters thats not the case, which makes it more confusing.
Any pointers would be of great help?

Resources