NamedParameterJdbcTemplate batchUpdate not working for merge - spring

I am running the below merge query using NamedParameterJdbcTemplate batchUpdate.
The batchUpdate(String sql, SqlParameterSource[] batchArgs) works for batchArgs with 1 item and does not work for multiple items. Below is the query and I renamed table column names.
The NamedParameterJdbcTemplate.batchUpdate works if run for each array item seperately or if run as NamedParameterJdbcTemplate .update()
Sql Query:
MERGE INTO tableName C1 USING (VALUES (:f1)) AS C2(Field1)
ON (C1.CMP = C2.CO_C)
WHEN MATCHED THEN
UPDATE SET Field2 = :date1, Field3 = :time1, Field4 =:userId
WHEN NOT MATCHED THEN
INSERT (Field5, Field1, Field4, Field2, Field3) VALUES (:offCC, :f1,:userId, :date1, :time1)
[err] SQL exception:
[err] Message: [jcc][t4][102][10040][4.22.29] Batch failure. The batch was submitted, but at least one exception occurred on an individual member of the batch. Use getNextException() to retrieve the exceptions for specific batched elements. ERRORCODE=-4229, SQLSTATE=null
[err] SQLSTATE: null
[err] Error code: -4229
[err] SQL exception:
[err] Message: VARIABLE IS NOT DEFINED OR NOT USABLE.
SQLCODE=-312, SQLSTATE=42618, DRIVER=4.22.29
[err] SQLSTATE: 42618
[err] Error code: -312
[err] SQL exception:
[err] Message: Error for batch element #1: VARIABLE IS NOT DEFINED OR NOT USABLE
[err] SQLSTATE: 42618
[err] Error code: -312

Related

Group By Statement within HQL

I'm doing a simple pull from an HQL database. Gives me an error only when I attempt to incorporate the GROUP BY statement
select
element1
,element2
,max(element3) as maxelement3
from HQLdb.HQLtable
group by element1,element2
Error message that I receive:
SELECT Failed. 35: (35) Error from server: error code: '1' error
message: 'Error while processing statement: FAILED: Execution Error,
return code 1 from org.apache.hadoop.hive.ql.exec.tez.TezTask

dynamic query with date data type in spel using spring data

I'm struggling in creating a dynamic query with null check on date in spel using spring data. My query is:
#Query(nativeQuery = true, value = "select a.* from TABLE a where"
+ "(:#{#DateFrom} is null or a.F_DATE >= trunc(:#{#DateFrom}))")
List<Acc> getAccList(#Param("DateFrom") #Temporal(TemporalType.DATE) Date datefrom);
When I run this query with valid date it works, but when I pass null date I get following error:
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
Stack trace:
Caused by: java.sql.SQLSyntaxErrorException: ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:802)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:205)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:861)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1145)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1267)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3449)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3493)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1491)
at com.ing.cbp.commons.util.logging.sql.LogablePreparedStatement.executeQuery(LogablePreparedStatement.java:77)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79)
... 78 common frames omitted
It seems oracle considers the NULL value a binary and than fails when it tries to perform trunc on it. Casting it to a Date should help. So the resulting query should look like this:
select a.* from TABLE a where (:#{#DateFrom} is null
or a.F_DATE >= trunc(CAST(:#{#DateFrom} AS DATE))
You need add one whitespace after 'where' keyword.
#Query(nativeQuery = true, value = "select a.* from TABLE a where "
+ "(:#{#DateFrom} is null or a.F_DATE >= trunc(:#{#DateFrom}))")
List<Acc> getAccList(#Param("DateFrom") #Temporal(TemporalType.DATE) Date datefrom);

Error querying database. Cause: java.lang.NullPointerException: QProfile is missing

I'm trying to restart SonarQube and ran into an issue with the QProfile is missing but I'm not sure what to do to address this.
2015.07.06 12:50:31 ERROR [o.s.s.p.PlatformServletContextListener] Fail to start server
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.NullPointerException: QProfile is missing
### The error may exist in org.sonar.core.qualityprofile.db.ActiveRuleMapper
### The error may involve org.sonar.core.qualityprofile.db.ActiveRuleMapper.selectAllKeysAfterTimestamp-Inline
### The error occurred while setting parameters
### SQL: SELECT r.plugin_rule_key as "rulefield", r.plugin_name as "repository", qp.kee as "profileKey" FROM active_rules a LEFT JOIN rules_profiles qp ON qp.id=a.profile_id LEFT JOIN rules r ON r.id = a.rule_id WHERE a.updated_at IS NULL or a.updated_at >= ?
### Cause: java.lang.NullPointerException: QProfile is missing

How to set JDBC prepared statement parameters when querying Amazon Redshift

I'm using JDBC to execute queries on Amazon Redshift. I have a java.sql.PreparedStatement object. When I set the parameters on the PreparedStatement object and then call:
preparedStatement.executeQuery();
with this query:
SELECT start_date from sometable_:year order by start_date desc limit 1
in the end, the query should look like this:
SELECT start_date from sometable_2010 order by start_date desc limit 1
I get this exception:
org.postgresql.util.PSQLException: ERROR: relation "sometable_$1" does not exist
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1592)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1327)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:192)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:350)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:254)
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:601)
at org.postgresql.ds.jdbc23.AbstractJdbc23PooledConnection$StatementHandler.invoke(AbstractJdbc23PooledConnection.java:477)
at com.sun.proxy.$Proxy159.executeQuery(Unknown Source)
at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:342)
at com.example.persistence.dao.impl.Redshift01JdbcDaoImpl.getSomeTableLastArchiveDate(Redshift01JdbcDaoImpl.java:46)
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:601)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy314.getSomeTableLastArchiveDate(Unknown Source)
at com.example.service.impl.someTableArchiveServiceImpl.process(SomeTableArchiveServiceImpl.java:69)
at com.example.service.impl.AbstractBatchServiceImpl.run(AbstractBatchServiceImpl.java:106)
at com.example.service.jms.JmsMessageListener.callBatchService(JmsMessageListener.java:72)
at com.example.service.jms.JmsMessageListener.onMessage(JmsMessageListener.java:136)
at org.springframework.jms.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:339)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:535)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:495)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:467)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)
at java.lang.Thread.run(Thread.java:722)
I would rather not do string concatenation, what am I doing wrong? The PreparedStatement setParameters method works for all other JDBC queries in my code base.
Thank you,
Tom
You can't use a prepared statement to replace arbitrary portions of the query dynamically. Only values, that don't affect the query plan, can be bound as parameters. You'll have to use String concatenation to do this.
Explanation: a PreparedStatement, as its name indicates, is a statement that is prepared by the database and can then be executed multiple times after with various parameters. Preparing the statement consists in parsing the query to examine which tables and columns are used, and build a plan to execute the query (which index to use, etc.).
The same plan is then used each time the statement is executed with various parameters. If the table from which the query must select data isn't even known when the statement is prepared, no plan can be computed. This is why the following query is fine:
select f.* from foo f where f.name = ?
but these ones aren't fine:
select f.* from ? f where f.name = 'bar' -- unknown table: the plan can't be computed
select f.? from foo f where f.name = 'bar -- unknown column: the plan can't be computed
select f.* from foo f where f.name ? 'bar' -- unknown operator: the plan can't be computed

Exception while trying to fetch an un-grouped-by column in jdbc

I have a table called test, defined as followed:
A bigint(20) NOT NULL
B bigint(20) NULL
I'm trying to execute the following prepared statement:
sql = "SELECT * FROM test GROUP BY B";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet rs = preparedStatement.executeQuery();
But I get the following exception:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 'anya_products.test.A' isn't in GROUP BY
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
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:1052)
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.executeQuery(PreparedStatement.java:2293)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
The exact same query works in SQLYog. What is the problem? JDBC limitation?
Thanks
Udi
Here's what I came up with. Not sure it's the most efficient or the only way, but it seems to at least work:
select test.a, test.b from test
inner join (select b, count(b) from test group by b having count(b) = 1) as c
on test.b = c.b

Resources