0

I want to create a PreparedStatement that either inserts a record, or updates it if the ID already exists.

    String sql = "INSERT INTO my_entity (id, name) VALUES(?, ?) ON DUPLICATE KEY UPDATE id=VALUES(id), name=VALUES(name)";      

    JdbcBatchItemWriter<MyEntity> w = new JdbcBatchItemWriter<>();
    w.setDataSource(ds);
    ItemPreparedStatementSetter<MyEntity> preparedStatementSetter = new ItemPreparedStatementSetter<MyEntity>() {
        @Override
        public void setValues(MyEntity item, PreparedStatement ps) throws SQLException {
            ps.setString(1, item.getId());
            ps.setString(2, item.getName());
        }
    };
    w.setItemPreparedStatementSetter(preparedStatementSetter);
    w.setSql(sql);

Result error: there is a syntax error for the ON attribute. Why?

[] 2015-01-09 11:31:17,764 ERROR : org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar; nested exception is org.postgresql.util.PSQLException: FEHLER: Syntaxerror at ?ON?
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:673)
    at org.springframework.batch.item.database.JdbcBatchItemWriter.write(JdbcBatchItemWriter.java:185)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:175)
    at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.scan(FaultTolerantChunkProcessor.java:578)
    at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.access$900(FaultTolerantChunkProcessor.java:50)
    at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$3.doWithRetry(FaultTolerantChunkProcessor.java:346)
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:263)
    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:193)
    at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:217)
    at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.write(FaultTolerantChunkProcessor.java:420)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:199)
    at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271)
    at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
    at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257)
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198)
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
    at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:386)
    at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:304)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128)
    at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:677)
    at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:695)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
caused by: org.postgresql.util.PSQLException: FEHLER: Syntaxerror at ?ON?
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:405)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2892)
    at org.springframework.batch.item.database.JdbcBatchItemWriter$1.doInPreparedStatement(JdbcBatchItemWriter.java:192)
    at org.springframework.batch.item.database.JdbcBatchItemWriter$1.doInPreparedStatement(JdbcBatchItemWriter.java:185)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:644)
    ... 39 more
membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • 5
    There is no `ON DUPLICATE KEY UPDATE` in Postgres which is clearly documented in the manual: http://www.postgresql.org/docs/current/static/sql-insert.html –  Jan 09 '15 at 10:39
  • What are my chances to overcame this in a single prepare statement? – membersound Jan 09 '15 at 10:44
  • 2
    http://stackoverflow.com/q/1109061/330315 –  Jan 09 '15 at 10:44

0 Answers0