I want to load SQL script files for my unit tests. As I am using Spring 2.5.2, I decided to use the SimpleJdbcTestUtils.executeScript() method to load my script file, using the following code:
DriverManagerDataSource dataSource = ... // getting my DataSource defined in my Spring context
SimpleJdbcTemplate template = new SimpleJdbcTemplate(dataSource);
Resource resource = new ClassPathResource("/create-table.sql");
SimpleJdbcTestUtils.executeSqlScript(template, resource, true);
If I write each SQL statement in one line in the create-table.sql file, then everything is ok. But if I write a statement on multiple lines, then I get an error, even if the statement is finished by a ;.
Working script :
CREATE TABLE T_FOO (ID NUMERIC PRIMARY KEY, DATEID TIMESTAMP, IS_ACTIVE INTEGER DEFAULT 0 NOT NULL);
CREATE TABLE T_BAR (ID NUMERIC PRIMARY KEY, DATEID TIMESTAMP, IS_ACTIVE INTEGER DEFAULT 0 NOT NULL);
Not working script:
CREATE TABLE T_FOO (
ID NUMERIC PRIMARY KEY,
DATEID TIMESTAMP,
IS_ACTIVE INTEGER DEFAULT 0 NOT NULL);
CREATE TABLE T_BAR (
ID NUMERIC PRIMARY KEY,
DATEID TIMESTAMP,
IS_ACTIVE INTEGER DEFAULT 0 NOT NULL);
Error on second file:
org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [CREATE TABLE T_FOO (]; nested exception is java.sql.SQLException: Unexpected token: in statement [CREATE TABLE T_FOO (]
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.translate(SQLStateSQLExceptionTranslator.java:111)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.translate(SQLErrorCodeSQLExceptionTranslator.java:322)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:404)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:519)
at org.springframework.jdbc.core.simple.SimpleJdbcTemplate.update(SimpleJdbcTemplate.java:237)
at org.springframework.test.jdbc.SimpleJdbcTestUtils.executeSqlScript(SimpleJdbcTestUtils.java:150)
at org.springframework.test.jdbc.SimpleJdbcTestUtils.executeSqlScript(SimpleJdbcTestUtils.java:113)
at foo.bar.HsqldbUtils.run(HsqldbUtils.java:95)
at foo.bar.SomeUnitTest.executeTests(SomeUnitTest.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:71)
at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.sql.SQLException: Unexpected token: in statement [CREATE TABLE T_FOO (]
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.jdbcStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.jdbcStatement.executeUpdate(Unknown Source)
at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:509)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:393)
As I am willing to create more complex tables, I prefer to write the SQL instruction in a more readable way, so using several lines. Is there a way to do that?
You're using Spring 2.5.2, but referring to the 2.5.6 documentation.
If you look at the javadoc for 2.5.2 (see here), you'll note that it doesn't support multi-line scripts.
This was apparently resolved in 2.5.4 (issue here).
You should upgrade to 2.5.6, or better yet, 3.0.x.
Related
I use hibernate to insert data in a table using autogenerated GUID, but insertion fails sometimes with duplicate GUID exception.
For Example:
From Logs , insertion fails for the first 2 attempts by printing the duplicate GUID '0500edac-0074-4324-3436-31444231342d'. The time taken are as follows
1st attempt :08-27-2018 04:27:00.012,
2nd attempt :08-27-2018 04:27:01.024,
3rd attempt was not logged ,as it was successful
but in the database I see a row with GUID '0500edac-0074-4324-3436-31444231342d' created at '08-27-2018 04:27:01.054'
So I am not sure why I am getting the exceptions for the first 2 attempts and then successfully it inserts the 3rd time.
SQL Table Properties: I have a SQL Server table named "DataHistory" with a column named
"DataHistoryGuid" with the following properties uniqueidentifier,ROWGUIDCOL,Primary Key column,newsequentialid .
Hibernate Properties:
I am using hibernate to store the data in that table, for the GUID column, I am using the
<id name="dataHistoryGuid" type="java.util.UUID" >
<column name="DataHistoryGuid"/>
<generator class="guid"/>
</id>
The following is the exception trace:
[event.def.AbstractFlushingEventListener:performExecutions:324]
Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not
insert: [com.testProj.dataprocessor.model.sql.SqlDataHistory]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2295)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2688)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:420)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:748)
at com.testProj.dataprocessor.common.sql.hibernate.HibernateSession.upsertDataHistory(HibernateSession.java:505)
at com.testProj.dataprocessor.common.sql.SqlStore.upsertDataHistory(SqlStore.java:92)
at com.testProj.dataprocessor.common.sql.SqlStore$$FastClassByCGLIB$$18d897d8.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:77)
at com.testProj.dataprocessor.model.performance.Profiler.profile(Profiler.java:15)
at sun.reflect.GeneratedMethodAccessor160.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:64)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:77)
at com.testProj.dataprocessor.common.sql.SqlRetryPolicy.retry(SqlRetryPolicy.java:20)
at sun.reflect.GeneratedMethodAccessor161.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:64)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
at com.testProj.dataprocessor.common.sql.SqlStore$$EnhancerByCGLIB$$f3a323cc.upsertDataHistory(<generated>)
at com.testProj.dataprocessor.dao.DataDAO.updateDataHistory(DataDAO.java:88)
at com.testProj.dataprocessor.eventhandler.DataHistoryEventHandler.doWork(DataHistoryEventHandler.java:34)
at com.testProj.dataprocessor.eventhandler.DataHistoryEventHandler.updateDiagnosticsHistory(DataHistoryEventHandler.java:28)
at com.testProj.dataprocessor.DataProcessorService.doWork(DataProcessorService.java:37)
at com.testProj.dataprocessor.DataProcessorService.process(DataProcessorService.java:24)
at com.testProj.dataprocessor.DataProcessorService.process(DataProcessorService.java:80)
at com.testProj.dataprocessor.DataProcessorService.postDataEventSync(DefaultDataProcessorService.java:41)
at com.testProj.dataprocessor.DataProcessorService.postDataEvent(DefaultDataProcessorService.java:36) at sun.reflect.GeneratedMethodAccessor272.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:173)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:89)
at org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:60)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:75)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:109)
at Caused by: java.sql.SQLException: Violation of PRIMARY KEY constraint 'PK_DataHistory_on_DataHistoryGuid'. Cannot insert duplicate key in object 'dbo.DataHistory'. The duplicate key value is (0500edac-0074-4324-3436-31444231342d).
at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:372)
at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2988)
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2421)
at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:671)
at net.sourceforge.jtds.jdbc.JtdsStatement.processResults(JtdsStatement.java:613)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:572)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeUpdate(JtdsPreparedStatement.java:727)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2275) ... 68 more
Assumptions:
1.As Sql Server websites has mentioned that 1 in a billion Guid's created will be a duplicate, so i don't expect duplicates to be present in my tables.
Although the question is focussed on Hibernate, the following line in the trace indicates that the database is rejecting the insert.
Caused by: java.sql.SQLException: Violation of PRIMARY KEY constraint 'PK_DataHistory_on_DataHistoryGuid'. Cannot insert duplicate key in object 'dbo.DataHistory'. The duplicate key value is (0500edac-0074-4324-3436-31444231342d).
This is more of a design issue than a problem with SQL Server or Hibernate. If an auto generated UUID as a PRIMARY KEY in the DataHistory table is your goal,
then you are much better off using the database to achieve this, rather than using Hibernate (or worse, rolling your own solution).
This is because the database is designed to avoid a collision of values, if a UNIQUE INDEX or PRIMARY KEY is specified.
See SQL UNIQUE Constraint
The task of creating the auto generated UUID is available for you, with PRIMARY KEY DEFAULT (NEWID()).
If you need to use the UUID later, then use a non primary key value to select the value after it has been created.
Example table:
CREATE TABLE dbo.DataHistory
(
DatahistoryGuid uniqueidentifier PRIMARY KEY DEFAULT (NEWID()),
history_row integer NOT NULL,
data_stuff nvarchar(4000) NOT NULL,
created_date datetime2 DEFAULT (GETDATE())
);
Try setting the insertable property to false in Hibernate. Do this for all columns defaulted by the database. For example:
#Column(name = "DatahistoryGuid", insertable=false)
#Column(name = "created_date", insertable=false)
This results in SQL similar to the following:
INSERT INTO dbo.DataHistory (history_row, data_stuff)
VALUES (1234, 'Joe Bloggs');
See Related Question
To get the DatahistoryGuid value, use a SELECT statement:
SELECT DatahistoryGuid from dbo.DataHistory where history_row = 1234;
SQL Fiddle Example
I am testing create method for my application .
In test I have embedded hsql db , and using Spring jdbcTemplate
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:/sql/db/db-schema.sql"/>
<jdbc:script location="classpath:/sql/db/db-data.sql"/>
</jdbc:embedded-database>
where db-data.sql is
INSERT INTO C_ContactType(name) VALUES ('bob_eng991');
INSERT INTO C_ContactType(name) VALUES ('bob_eng2');
INSERT INTO C_ContactType(name) VALUES ('bob_eng3');
INSERT INTO C_ContactType(name) VALUES ('bob_eng422');
db-schema.sql is
CREATE TABLE C_ContactType (
contactTypeId INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
name VARCHAR(90) NOT NULL,
deletedOn DATETIME,
deletedBy INT
);
and my test is
#Test
void test_createClassifier() {
mockMvc.perform(MockMvcRequestBuilders.post("/classifiers/{category}", "ContactType")
.contentType(MediaType.APPLICATION_JSON)
.param("languageId", String.valueOf(3))
.content("{ \"name\": \"bob_eng100\"}".getBytes()))
.andExpect(status().isOk())
}
running test I get errors here
ResultSet rs = jdbcTemplate.insertWithKey(tablePath,
insert -> insert.columns(paths.toArray(new Path[paths.size()]))
.values(params.toArray(new Object[paths.size()]))
.executeWithKeys());
where tablePath indicates to "C_ContactType" ,
paths is an ArrayList with my table columns except autoIncrement field ,
and params is an ArrayList with values (except autoIncrement field)
And logs
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: contactTypeId
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.Table.getColumnIndex(Unknown Source)
at org.hsqldb.Table.getColumnIndexes(Unknown Source)
at org.hsqldb.StatementDML.setGeneratedColumnInfo(Unknown Source)
at org.hsqldb.StatementManager.compile(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
... 82 more
The error show the name of the column requested by the framework. The name is in mixed case contactTypeId.
Your table declaration does not have double-quote characters around the table and column names, therefore the names are converted to upper-case by the database engine. You need to change the table definition:
CREATE TABLE C_ContactType (
"contactTypeId" INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
I have a report called Analysis which is populated by this simple query:
SELECT * FROM TB_ANL analysis WHERE analysis.CD_ANL = $P{FILTER}
Only one element will be selected (CD_ANL is unique).
When I edit this query in iReports (version 4.7), the Edit Query window actually shows the columns of the table (so it recognizes the table) and I successfully compile the report.
When I try to run it in my server, it accuses a ORA-00942 and says:
net.sf.jasperreports.engine.JRException: Error executing SQL statement for : AnalysisTemplate
at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:229)
at net.sf.jasperreports.engine.fill.JRFillDataset.createQueryDatasource(JRFillDataset.java:758)
at net.sf.jasperreports.engine.fill.JRFillDataset.initDatasource(JRFillDataset.java:623)
at net.sf.jasperreports.engine.fill.JRBaseFiller.setParameters(JRBaseFiller.java:1160)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:802)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:746)
at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:58)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:417)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:247)
at gov.chesf.leilaovenda.nucleo.negocio.analise.RelatorioGerador.gerarRelatorio(RelatorioGerador.java:57)
at gov.chesf.leilaovenda.web.analise.analise.action.Index.gerarAnalise(Index.java:725)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
...
Caused by: java.sql.SQLException: ORA-00942: table or view does not exist
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:813)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1049)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:854)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1154)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3370)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3415)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:222)
... 85 more
So, basically, the problem is: I can view the table in iReports and in SQLDeveloper but I can't fill the report with it because the table or view "Does not exist". What is wrong with it? Is there any other reason why Jasper wouldn't be able to see the table?
Things I've done before posting here:
I Granted the user that Jasper is using.
The table exists, yes.
I checked the connection in Jasper. It's the same that Hibernate is using.
Problem solved.
Here was the problem:
It had nothing to do with the iReport itself, but with the schema being used by the user that the connection was logging in as.
The table TB_ANL should be referenced as OWNER.TB_ANL and not just as TB_ANL.
Possible solutions to this:
1) Update the schema to contain TB_ANL
2) Create a Synonym for OWNER.TB_ANL as TB_ANL so everytime you reference the table it will look in OWNER's schema.
I have a file(this file actually has tab separated values) which has to be written into one of the database tables. This file can contain duplicate entries as well. I am processing the records in the file in set of 5000, so I first parse these first 5000 records in the file if they contain any duplicate entries I simply ignore the duplicates and write the unique records among them to the database and again process next 5000 records in the similar fashion till EOF is reached. Now while writing these 5000 records it is possible that there are duplicates between the sets of 5000 records and if so happens(then database throws the DomainObjectExistsException) then I catch the exception and simply update the record. I am performing the update operation like this:
getHibernateTemplate().saveOrUpdate(femtoFactoryData);
Where femtoFactoryData is a java Object(POJO) which has to be written into the database table constructed from the tab-separated values in the file. The Primary Key of the table is nothing but the ID of the Femto and the state(Temporary/Permanent).
But while performing this update operation I am getting:
org.hibernate.exception.ConstraintViolationException
Here is the stacktrace from my program:
org.hibernate.exception.ConstraintViolationException: could not insert: [com.airvana.anp.model.db.domainobjects.FemtoFactoryData]
at com.airvana.anp.model.db.impl.DbManagerGlobalUtils.convertException(DbManagerGlobalUtils.java:68)
at com.airvana.anp.model.db.impl.FemtoFactoryDataDAOImplHelper.updateFemtoFactoryData(FemtoFactoryDataDAOImplHelper.java:302)
at com.airvana.anp.model.db.impl.FemtoFactoryDataDAOImpl.updateFemtoFactoryData(FemtoFactoryDataDAOImpl.java:149)
at com.airvana.anp.model.oss.imports.common.DataRecordDAOHelperImpl.updateRecord(DataRecordDAOHelperImpl.java:725)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
at $Proxy89.updateRecord(Unknown Source)
at com.airvana.anp.model.oss.imports.parser.ParseControllerImpl.saveDupFactoryRecordsInDb(ParseControllerImpl.java:477)
at com.airvana.anp.model.oss.imports.parser.ParseControllerImpl.parseFile(ParseControllerImpl.java:111)
at com.airvana.anp.model.oss.imports.FactoryOperationsManagerImpl.onAllocation(FactoryOperationsManagerImpl.java:192)
at com.airvana.anp.model.resource.impl.CallbackWorkerJob.run(CallbackWorkerJob.java:43)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
Caused by: org.springframework.dao.DataIntegrityViolationException: could not insert: [com.airvana.anp.model.db.domainobjects.FemtoFactoryData]; nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [com.airvana.anp.model.db.domainobjects.FemtoFactoryData]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:624)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.merge(HibernateTemplate.java:820)
at com.airvana.anp.model.db.impl.FemtoFactoryDataDAOImplHelper.updateFemtoFactoryData(FemtoFactoryDataDAOImplHelper.java:299)
... 16 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [com.airvana.anp.model.db.domainobjects.FemtoFactoryData]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2272)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2665)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:56)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1004)
at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:420)
... 19 more
Caused by: java.sql.SQLException: ORA-00001: unique constraint (ANPDB.SYS_C008651) violated
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:955)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1168)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3316)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3400)
at weblogic.jdbc.wrapper.PreparedStatement.executeUpdate(PreparedStatement.java:128)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2252)
... 29 more
You're not handling duplicates properly since there's obviously constraint violation regarding unique keys.
I'd suggest eliminating those duplicates entirely before inserting them into database.
Remember: the database is your last line of defense. Ignoring the poetic aspect, that's basically saying that you should do whatever possible to insert into your database exactly what's needed. Nothing more, nothing less. Filter, remove duplicates, whatever on your server side before sending it to database.
I want to generate UUID for a unique string, i am using the following code:-
thread.createSession();
HexGenerator gen1 = new HexGenerator();
gen1.setHexId("2");
thread.ses.save(gen1);
gen1 = (HexGenerator) thread.ses.load(HexGenerator.class, gen1.getHexId());
System.out.println("gen1-->" + gen1.getHexId());
thread.commit();
Below is my hibernate file:-
<class name="entity.HexGenerator" table="dual">
<id name="hexId" type="string" unsaved-value="null">
<generator class="uuid.hex"/>
</id>
</class>
UUId is generated properly, but i am getting an error when the complete transaction is committed. as in the following error comes.
Exception in thread "main" - Could not synchronize database state with session
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.ofss.test.hibernate.HibernateThread.commit(HibernateThread.java:29)
at com.ofss.test.hibernate.HibernateThread.main(HibernateThread.java:57)
Caused by: java.sql.BatchUpdateException: ORA-00904: "HEXID": invalid identifier
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10698)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 9 more
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.ofss.test.hibernate.HibernateThread.commit(HibernateThread.java:29)
at com.ofss.test.hibernate.HibernateThread.main(HibernateThread.java:57)
Caused by: java.sql.BatchUpdateException: ORA-00904: "HEXID": invalid identifier
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10698)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
You can't insert or update on the Oracle dual virtual table. You just can use it at select queries.
So, your line thread.ses.save(gen1) is what generates the error. I think that if you just delete this line, the error will be fixed.
But I don't really understand why you need to access the database to generate your UUID, which seems to be generated at the HexGenerator class (or maybe at the "uuid.gen" class referenced at the hibernate file).
To overcome the above problem, i mean to generate the UUID, now I have decided to use two method, either to use java.util.UUID.randomUUID() or to write my own logic to generate the same using bits array and then randomizing it.
first, your code looks a little bit strange. You create instance of HexGenerator:
HexGenerator gen1 = new HexGenerator();
use it and immediately override using some unknown for me API that uses dynamic class loading.
thread.ses.load(HexGenerator.class, gen1.getHexId())
Then you call getHexId() again. I believe that code
new HexGenerator().getHexId()
will generate ID that you need.
But I think it is not yet the reason for failure. Unfortunately you did not provide any information about you DB schema. I believe that you ID is simply defined as number, it cannot accept strings. Check it again and please provide more details if this is not the reason.