Play framework: Enabling database evolution for oracle - oracle

There is a bug in play framework. According to this bug, play_evolutions can not instantiate for Oracle databases.
As mentioned in this question I am using following script for generating play_evolutions table manually:
CREATE TABLE play_evolutions
(
id Number(10,0) Not Null Enable,
hash VARCHAR2(255 Byte),
applied_at Timestamp Not Null,
apply_script clob,
revert_script clob,
state Varchar2(255),
last_problem clob,
CONSTRAINT play_evolutions_pk PRIMARY KEY (id)
);
with generating table manually, evolutions are applied, but program stops with following stack trace:
Unexpected exception
NullPointerException: null
No source available, here is the exception stack trace:
->java.lang.NullPointerException:
play.api.db.evolutions.Evolution.<init>(Evolutions.scala:36)
play.api.db.evolutions.Evolutions$$anonfun$databaseEvolutions$1.apply(Evolutions.scala:378)
play.api.db.evolutions.Evolutions$$anonfun$databaseEvolutions$1.apply(Evolutions.scala:374)
play.api.libs.Collections$.loop$1(Collections.scala:29)
play.api.libs.Collections$.unfoldLeft(Collections.scala:33)
play.api.db.evolutions.Evolutions$.databaseEvolutions(Evolutions.scala:374)
play.api.db.evolutions.Evolutions$$anonfun$evolutionScript$2.apply(Evolutions.scala:332)
play.api.db.evolutions.Evolutions$$anonfun$evolutionScript$2.apply(Evolutions.scala:330)
scala.Option.map(Option.scala:145)
play.api.db.evolutions.Evolutions$.evolutionScript(Evolutions.scala:330)
play.api.db.evolutions.EvolutionsPlugin$$anonfun$onStart$1$$anonfun$apply$1.apply$mcV$sp(Evolutions.scala:486)
play.api.db.evolutions.EvolutionsPlugin.withLock(Evolutions.scala:531)
play.api.db.evolutions.EvolutionsPlugin$$anonfun$onStart$1.apply(Evolutions.scala:485)
play.api.db.evolutions.EvolutionsPlugin$$anonfun$onStart$1.apply(Evolutions.scala:483)
scala.collection.immutable.List.foreach(List.scala:383)
play.api.db.evolutions.EvolutionsPlugin.onStart(Evolutions.scala:483)
play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
scala.collection.immutable.List.foreach(List.scala:383)
play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:91)
play.api.Play$$anonfun$start$1.apply(Play.scala:91)
play.api.Play$$anonfun$start$1.apply(Play.scala:91)
play.utils.Threads$.withContextClassLoader(Threads.scala:21)
play.api.Play$.start(Play.scala:90)
play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:142)
play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:115)
scala.Option.map(Option.scala:145)
play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:115)
play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:113)
scala.util.Success.flatMap(Try.scala:230)
play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:113)
play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:105)
scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361)
scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

Origin of this problem is empty Downs part in sql file.
I report it as issue #3033 in play frame work community

Related

How to use keyword VALUE as a field name in H2 database

I inherited a project where in UnitTests an H2 database is being used. On the startup of the project a lot of tables are created and populated with data.
CREATE TABLE SRC_FIELD_VALUE
( ID NUMBER IDENTITY,
INPUT_SRC_FIELD_REF_ID NUMBER,
VALUE VARCHAR2(255),
DESCRIPTION VARCHAR2(255)
);
We recently migrated to the latest version of H2 : 2.1.214
In my POM.XML I added "NON_KEYWORDS=VALUE,ID" to the end of definition but still got an exception :
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "CREATE TABLE SRC_FIELD_VALUE ( ID NUMBER IDENTITY, INPUT_SRC_FIELD_REF_ID NUMBER, [*]VALUE VARCHAR2(255), DESCRIPTION VARCHAR2(255) )"; expected "identifier"; SQL statement:
CREATE TABLE TC_RULE_COMP_DATA ( ID NUMBER IDENTITY, RULE_REF_ID NUMBER, SORT_ORDER NUMBER, VALUE CLOB ) [42001-214]
I also tried to put double quote around "VALUE" but got the same exception. It's interesting that "ID" is not getting considered as KEYWORD though.
What are my options here? I can't rename the fields.

ERROR: duplicate key value violates unique constraint "spring_session_attributes_pk"\n Detail: Key (session_primary_id, attribute_name)

Currently, I'm using:
Spring boot 2.2.2
Spring jdbc 2.5.0
Spring core 2.5.0
Sometimes, I got errors when accessing my endpoints, here is the stack trace, this happen after upgrading my library from:
spring boot 2.1.7
spring jdbc 2.1.8
spring core 2.1.8
Handle DataIntegrityViolationException: PreparedStatementCallback;
SQL [INSERT INTO SPRING_SESSION_ATTRIBUTES(SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) SELECT PRIMARY_ID, ?, ? FROM SPRING_SESSION WHERE SESSION_ID = ?];
ERROR: duplicate key value violates unique constraint \"spring_session_attributes_pk\"
Detail: Key (session_primary_id, attribute_name)=(a9427ef5-92a4-4845-8769-e034c3b50b70, SPRING_SECURITY_CONTEXT) already exists.; nested exception is org.postgresql.util.PSQLException:
ERROR: duplicate key value violates unique constraint \"spring_session_attributes_pk\"
Detail: Key (session_primary_id, attribute_name)=(a9427ef5-92a4-4845-8769-e034c3b50b70, SPRING_SECURITY_CONTEXT) already exists.
org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO SPRING_SESSION_ATTRIBUTES(SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) SELECT PRIMARY_ID, ?, ? FROM SPRING_SESSION WHERE SESSION_ID = ?];
ERROR: duplicate key value violates unique constraint \"spring_session_attributes_pk\"
Detail: Key (session_primary_id, attribute_name)=(a9427ef5-92a4-4845-8769-e034c3b50b70, SPRING_SECURITY_CONTEXT) already exists.; nested exception is org.postgresql.util.PSQLException:
ERROR: duplicate key value violates unique constraint \"spring_session_attributes_pk\"
Detail: Key (session_primary_id, attribute_name)=(a9427ef5-92a4-4845-8769-e034c3b50b70, SPRING_SECURITY_CONTEXT) already exists.
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:243)
Here is my session tables:
CREATE TABLE APP_SPRING_SESSION (
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
EXPIRY_TIME BIGINT NOT NULL,
PRINCIPAL_NAME VARCHAR(100),
CONSTRAINT APP_SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);
CREATE UNIQUE INDEX APP_SPRING_SESSION_IX1 ON APP_SPRING_SESSION (SESSION_ID);
CREATE INDEX APP_SPRING_SESSION_IX2 ON APP_SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX APP_SPRING_SESSION_IX3 ON APP_SPRING_SESSION (PRINCIPAL_NAME);
CREATE TABLE APP_SPRING_SESSION_ATTRIBUTES (
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BYTEA NOT NULL,
CONSTRAINT APP_SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
CONSTRAINT APP_SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES APP_SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);
Does anyone know how to fix the problem?
These errors mean that there are already records with such keys in your database.
You can clear the database or change the keys and the Insert queries.

sql script not running

Here is a code snippet of a sql script which is giving me error,I have to generate a sequence on the primary_key of the table without using triggers in oracle:
CREATE SEQUENCE t1_seq START WITH 1 INCREMENT BY 1;
DROP TABLE CPR_SOURCE_SYSTEM_METADATA;
CREATE TABLE CPR_SOURCE_SYSTEM_METADATA
(
SYSTEM_ID NUMBER(4) NOT NULL t1_seq.nextval,
SYSTEM_NAME VARCHAR2(200),
DATE_FORMAT VARCHAR2(200),
CREATED_BY VARCHAR2(200),
MODIFIED_BY VARCHAR2(200),
CREATED_ON NUMBER(20),
MODIFIED_ON NUMBER(20),
IS_DELETED VARCHAR2(1),
CONSTRAINT "CPR_SOURCE_SYSTEM_PK" PRIMARY KEY ("SYSTEM_ID")
);
It is giving me the below error :
DROP TABLE CPR_SOURCE_SYSTEM_METADATA
* ERROR at line 1: ORA-00942: table or view does not exist
SYSTEM_ID NUMBER(4) NOT NULL t1_seq.nextval,
* ERROR at line 3: ORA-00907: missing right parenthesis
Not able to figure out the error,can anyone help??
SYSTEM_ID NUMBER(4) NOT NULL t1_seq.nextval,
The t1_seq.nextval segment is not valid - you cannot specify an auto-incrementing column like that.
The SQL parser is expecting to see:
SYSTEM_ID NUMBER(4) NOT NULL,
and throws the exception as the comma is not where it expects.
In Oracle 12c you can use an identity column but in earlier versions you will either need to:
Use the sequence in the SQL insert statement;
Use a trigger to insert the correct sequence value; or
Create a stored procedure to handle inserts and manage the sequence through that (disallowing direct inserts that could bypass this).

JDBC retrieve foreign keys columns name (sybase ase)

I'm trying to retrieve FK of a given table with JDBC metadata.
For that, I'm using the "getImportedKeys" function.
For my table 'cash_mgt_strategy', it give in resultset:
PKTABLE_CAT : 'HAWK'
PKTABLE_SCHEM : 'dbo'
PKTABLE_NAME : 'fx_execution_strategy_policy'
PKCOLUMN_NAME : 'fx_execution_strategy_policy_id'
FKTABLE_CAT : 'HAWK'
FKTABLE_SCHEM : 'dbo'
FKTABLE_NAME : 'cash_mgt_strategy'
FKCOLUMN_NAME : 'fx_est_execution_strategy_policy'
KEY_SEQ : '1'
UPDATE_RULE : '1'
DELETE_RULE : '1'
FK_NAME : 'fk_fx_est_execution_strategy_policy'
PK_NAME : 'cash_mgt_s_1283127861'
DEFERRABILITY : '7'
The problem is that the "FKCOLUMN_NAME : 'fx_est_execution_strategy_policy'" is not a real column of my table, but it seems to be truncated? (missing "_id" at the end)
When using an official Sybase sql client (Sybase Workspace), displaying the DDL of the table give for this constraint / foreign key:
ALTER TABLE dbo.cash_mgt_strategy ADD CONSTRAINT fk_fx_est_execution_strategy_policy FOREIGN KEY (fx_est_execution_strategy_policy_id)
REFERENCES HAWK.dbo.fx_execution_strategy_policy (fx_execution_strategy_policy_id)
So I'm wondering how to retrieve the full FKCOLUMN_NAME ?
Note that I'm using jconnect 6.0.
I've tested with jconnect 7.0, same problem.
Thanks
You haven't provided your ASE version so I'm going to assume the following:
dataserver was running ASE 12.x at some point (descriptor names limited to 30 characters)
dataserver was upgraded to ASE 15.x/16.x (descriptor names extended to 255 characters)
DBA failed to upgrade/update the sp_jdbc* procs after the upgrade to ASE 15.x/16.x (hence the old ASE 12.x version of the procs - descriptors limited to 30 characters - are still in use in the dataserver)
If the above is true then sp_version should show the older versions of the jdbc procs running in the dataserver.
The (obvious) solution would be to have the DBA load the latest version of the jdbc stored procs (typically found under ${SYBASE}/jConnect*/sp).
NOTE: Probably wouldn't hurt to have the DBA review the output from sp_version to see if there are any other upgrade scripts that need to be loaded (eg, installmodel, installsecurity, installcommit, etc).
Ok, so I've done some search on my DB server and I've found the code of stored proc sp_jdbc_importkey. In this code can see:
create table #jfkey_res(
PKTABLE_CAT varchar(32) null,
PKTABLE_SCHEM varchar(32) null,
PKTABLE_NAME varchar(257) null,
PKCOLUMN_NAME varchar(257) null,
FKTABLE_CAT varchar(32) null,
FKTABLE_SCHEM varchar(32) null,
FKTABLE_NAME varchar(257) null,
FKCOLUMN_NAME varchar(257) null,
KEY_SEQ smallint,
UPDATE_RULE smallint,
DELETE_RULE smallint,
FK_NAME varchar(257),
PK_NAME varchar(257) null)
create table #jpkeys(seq int, keys varchar(32) null)
create table #jfkeys(seq int, keys varchar(32) null)
The temporary tables #jpkeys and #jfkeys used to store the column names (for PK and FK) are typed with varchar(32) instead of 257!!
Need to search how to patch / update theses stored proc now.

SqlExceptionHelper - Duplicate entry for Unique key Using Spring Data JPA

Here is the situation:
I have 3 tables - Dummy, A and B - where A and B have One-To-Many
relationship, and Dummy is stand alone
These tables have corresponding JPA entities in the data layer. I am
using Repository design pattern, so accessing these entities via their corresponding
service implementations.
I am making exact sequence of calls to these entities:
Get an entity for ID = xxx
Display the entity ID and name (or whatever)
Update a field using entity.setField(YYY)
push it back to DB using: entityService.updateEntity(entity)
The above sequence from #4 to #7 works like a charm for Dummy table. But fails to execute for the A and B. The exception is:
ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Duplicate entry <The name here> for key 'name_UNIQUE'
Exception in thread "main" org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.ConstraintViolationException: could not execute statement; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:321)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
The field that I am updating is not unique. The entities have exactly same structure with some additional columns here and there.
Here is the code for Dummy Entity:
DummyEntity dummyEntity = dummyService.findDummyEntity(16L);
System.out.println(">>> Name is: " + dummyEntity.getName() + " with ID: " + dummyEntity.getId());
dummyEntity.setName("New Name");
dummyEntity.setRank(3333333);
dummyService.updateDummyEntity(dummyEntity);
Repeating the exact same steps for the remaining entities A and B.
So what am I doing wrong? Any pointers will be greatly appreciated.
UPDATE:
#erencan - yes, I double checked that. Here is what I observed after posing the question here. The Table A and B (the troublesome ones) has this issue:
When I ask repository service to return me an instance for a given ID for Table A and B, it returns them alright
when a change is made to that instance using the setXXX(), and updateEntity() or saveEntity() is called (as shown using the demo entity code above), the save/update inserts a new entity in the table with exact attribute values as the old one, but with the new changes incorporated (this was observed by removing the unique key constraint on the Table A and B).
Later, when I query these newly created entities using their ID in the JPA/Java code, and perform the exact same steps (change some attribute and call save/update on the repository), these newly created entities (rows in the db table) get updated in exactly the manner expected.
So it seems that the original entity (row) is somehow 'locked' and updates are prevented. Therefore, the JPA save/update calls simply tries to create a fresh one instead; and since the fresh entity still has the same set of attribute values, any UNIQUE key constraint will start complaining (of course)
I did some tests on the existing tables (ETL'd into the DB), and find this behavior consistent: If the entity is NOT created by JPA, then JPA can read the data alright, but cannot update them; if the entity IS created by JPA, then JPA can read AND update them alright.
Not sure how this happens though (yet). Here is the schema of Table A and B:
CREATE TABLE IF NOT EXISTS `mydbschema`.`table-B` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT 'This is PK',
`name` VARCHAR(100) NULL,
`city` VARCHAR(50) NOT NULL,
`state` VARCHAR(30) NOT NULL,
`zip` VARCHAR(5) NOT NULL,
`country` VARCHAR(50) NOT NULL,
`overall_rank` INT NULL,
`inserted` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`insert_src_ver_id` INT NULL,
`updated` TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
`update_src_ver_id` INT NULL,
`version` INT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `name_UNIQUE` (`name` ASC))
ENGINE = InnoDB;
Another one:
CREATE TABLE IF NOT EXISTS `mydbschema`.`table-A` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT 'This is PK',
`full_name` VARCHAR(200) NULL,
`gender` VARCHAR(1) NULL,
`year_of_birth` VARCHAR(4) NULL,
`title_code` VARCHAR(6) NULL,
`business_role` VARCHAR(30) NULL,
`graduation_year` VARCHAR(4) NULL,
`residency` VARCHAR(500) NULL,
`table-B_id` INT NULL,
`npi_num` VARCHAR(10) NULL,
`upin` VARCHAR(20) NULL,
`dea_num` VARCHAR(20) NULL,
`dea_expire_date` VARCHAR(10) NULL,
`year_started_practicing` VARCHAR(4) NULL,
`high_prescriber` VARCHAR(1) NULL,
`board_action` VARCHAR(1) NULL,
`mdi_qscore` INT NOT NULL DEFAULT 0,
`mdi_cscore` INT NOT NULL DEFAULT 0,
`aco_id` INT NULL,
`npp` INT NULL,
`medicaid_id` VARCHAR(50) NULL,
`medicaid_state` VARCHAR(2) NULL,
`medicare_id` VARCHAR(50) NULL,
`medicare_state` VARCHAR(2) NULL,
`medicare_provider_flag` VARCHAR(1) NULL,
`inserted` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`insert_src_ver_id` INT NULL,
`updated` TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
`update_src_ver_id` INT NULL,
`version` INT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `hdsphy_id_UNIQUE` (`id` ASC),
UNIQUE INDEX `npi_num_UNIQUE` (`npi_num` ASC),
UNIQUE INDEX `dea_num_UNIQUE` (`dea_num` ASC),
CONSTRAINT `fk_table-A_table-B`
FOREIGN KEY (`table-B_id`)
REFERENCES `mydbschema`.`table-B` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
ENGINE = InnoDB;
Here is the FULL Stack trace:
2013-09-30 10:20:49,705 [main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Duplicate entry '1568673648' for key 'npi_num_UNIQUE'
Exception in thread "main" org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.ConstraintViolationException: could not execute statement; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:321)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:84)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy60.save(Unknown Source)
at com.mdinsider.platform.domain.PhysicianServiceImpl_Roo_Service.ajc$interMethod$com_mdinsider_platform_domain_PhysicianServiceImpl_Roo_Service$com_mdinsider_platform_domain_PhysicianServiceImpl$updatePhysician(PhysicianServiceImpl_Roo_Service.aj:48)
at com.mdinsider.platform.domain.PhysicianServiceImpl.updatePhysician(PhysicianServiceImpl.java:1)
at com.mdinsider.platform.domain.PhysicianService_Roo_Service.ajc$interMethodDispatch1$com_mdinsider_platform_domain_PhysicianService_Roo_Service$com_mdinsider_platform_domain_PhysicianService$updatePhysician(PhysicianService_Roo_Service.aj)
at com.mdinsider.platform.mediblip.engine.TestDBSave.saveMDIQualityScore(TestDBSave.java:94)
at com.mdinsider.platform.mediblip.engine.TestDBSave.main(TestDBSave.java:142)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1316)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:898)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
at com.sun.proxy.$Proxy31.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:345)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:334)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:319)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
... 12 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136)
at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2975)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3487)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:214)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:194)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:178)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:321)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:286)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
at org.hibernate.ejb.event.EJB3MergeEventListener.saveWithGeneratedId(EJB3MergeEventListener.java:71)
at org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:236)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:216)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:154)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:898)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:902)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:889)
... 31 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1568673648' for key 'npi_num_UNIQUE'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1039)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2624)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2127)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2427)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2345)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2330)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)
Alright, problem solved. After trying out various ways to isolate the problem, I saw that any rows added manually or by the ETL will be selectively treated for this exception. Any rows added by the Spring Data JPA/Java code will work fine.
Hence, the issue was with manually inserted rows. Then I realized that VERSION field was sitting there with NULL value for those manually inserted rows. When I set the values to 0, the manually inserted rows became acceptable to JPA.
Another alternative is to not have version field at all in of your tables.
Hope this helps folks who come across the same problem.

Resources