My problem seems to be very simple but I have hard time resolving it.
I want to alter an PostgreSQL sequence using Hibernate via native sql query (other solutions are also welcomed) using next code:
Query query = getSession()
.createSQLQuery("ALTER SEQUENCE users_id_seq RESTART WITH ?")
.setInteger(0, 1);
query.executeUpdate();
But I am getting this error:
Hibernate:
ALTER SEQUENCE users_id_seq RESTART WITH ?
hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 42601
hibernate.engine.jdbc.spi.SqlExceptionHelper - ERROR: syntax error at or near "$1"
Best I'm aware, you cannot prepare that statement.
If hibernate allows it, emulate the prepared statement, instead of sending it to the server. If not, sanitize the variable and issue the final statement directly.
Alternatively, wrap it in a function with dynamic SQL:
http://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN
Related
My following native query is not working:
Query createNativeQuery = entityManager.createNativeQuery(
"select id from cscache where id=? for update ");
Environment Details:
Mysql 5.6
Jboss 5.1
JPA 1.0
Error:
2014-12-12 10:20:14,581 WARN [org.hibernate.util.JDBCExceptionReporter]
SQL Error: 1064, SQLState: 42000 (http-0.0.0.0-8543-3:)
2014-12-12 10:20:14,581 ERROR [org.hibernate.util.JDBCExceptionReporter]
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit 2' at line 1 (http-0.0.0.0-8543-3:)
For Update basically puts a lock on rows, to achieve the same using JPA you need to use Lock Modes. To set the lock, you can use EntityManager or TypeQuery and use LockModeType.PESSIMISTIC_WRITE.
Refer this article
I haven't actually done a for update in hibernate, but I believe you can (and should?) do it on the Session or query object. Why not let hibernate do it instead of executing a native query?
According to the documentation on locking (Chapter 5: Locking, you can set the lock mode on either the session or the query.
Cscache cscache = (Cscache )session.get( Cscache.class, id, LockOptions.UPGRADE );
Specifying the LockOptions should result in a SELECT ... FOR UPDATE being executed.
Not familiar with JPA specifically, but it appears you're not telling it what the value of ? is. Check out setParameter.
The function CreateQuery(string) in java.persistence.Query is returning a different query from what I requested.
My input string to the function is:
from Underlying where (SUBSTRING(ticker, (charindex('.', ticker) +
1), (len(ticker) - charindex('.', ticker))) in (:exchanges) order by
ticker
When I call getResultList() on the Query, I see the following sql in my log:
Hibernate: select underlying0_.id as id63_, underlying0_.updated_date
as updated2_63_, underlying0_.updated_user as updated3_63_,
underlying0_.version as version63_, underlying0_.adr as adr63_,
underlying0_.desk as desk63_, underlying0_.enabled as enabled63_,
underlying0_.forward_start_enabled as forward8_63_,
underlying0_.ticker as ticker63_, underlying0_.vol_shift_type as
vol10_63_ from underlyings underlying0_ where
(substring(underlying0_.ticker, charindex('.', underlying0_.ticker)+1)
in (?)) order by underlying0_.ticker
This is query is not a valid SQL Server 2008 query and as expected, I received an error:
SQL Error: 174, SQLState: S0001
The substring function requires 3 argument(s).
Any one know what is going on here?
FYI, I have tried the following two dialects 1) org.hibernate.dialect.SQLServer2008Dialect, and 2) org.hibernate.dialect.SQLServer2008Dialect
Issue is with function charindex. It is not available in the dialect, therefore causes incorrect mapping. Changing this to the HQL function "locate" (keeping args constant) fixed the issue. My query now works in SQL Server 2008:
...where (substring(underlying0_.ticker, charindex('.',
underlying0_.ticker)+1, len(underlying0_.ticker)-charindex('.',
underlying0_.ticker)) in (?))...
Error clearly mention that SUBSTRING() function require 3 Arguments you are passing 2. thus error is in your query.
read about SUBSTRING() Function
I'm trying to track the amount of redo being generated during a database session with the following query:
SELECT a.name, b.VALUE
FROM v$statname a, v$mystat b
WHERE a.statistic# = b.statistic# AND a.name = 'redo size';
This query works directly in SQL*Plus and Toad, but I get an ORA-00911 exception using JDBC, and I've narrowed it down to the "statistic#" column name.
How do I get around this?
The column name statistic# is not the problem.
My bet is that you also send the terminating ; from inside your Java program.
But you may not include the the ; when executing a SQL statement through JDBC (at least not in Oracle and some other DBMS).
Remove the ; from your SQL String and it should be fine.
put it in double quotes - that should let you call a field anything in Oracle
Switch on JDBC logging, check your driver documentation for how to do this. In the JDBC log you see the actual statement prepared and executed in the DB. This eliminates one possible cause for the error.
I am connecting to a DB2 database (DB2 v9.7.400.501) from my Java web application using the IBM DB2 Type 4 driver (db2jcc4.jar). When I try to execute an SQL statement like this,
SELECT * FROM USERS WHERE UPPER(USERNAME) = UPPER('testuser');
I get the following exception:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error:
SQLCODE=-104, SQLSTATE=42601, SQLERRMC=;;=
UPPER('testuser');END-OF-STATEMENT, DRIVER=4.12.55
The problem is from the UPPER function since, a normal select statement executes normally.
Maybe you should use is this way:
SELECT * FROM USERS WHERE UPPER(USERNAME) LIKE UPPER('testuser');
Your code with '=' is seems ok for SQLite but don't know anbout db2.
UPD. After some investigation, I can say that error is cause by Java code which tries to execute multiple statements in one query using ';' as a delimiter.
You should try using the PreparedStatement, addBatch() and executeBatch() for multiple statements.
UPD2. This is DB2 related issue. PostgreSQL, afaik, allows multiple statements in single query.
This query works when I input it through phpmyadmin.
INSERT INTO conversation (user_id) VALUES (?);
INSERT INTO conversation (conversation_id, user_id)
VALUES ((SELECT LAST_INSERT_ID()), ?)
However when I send that query using jdbc and java I get an error -
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO conversation (conversation_id, user_id) VALUES ((SELECT LAST_INSERT_' at line 1"
I am using the exact same query. I checked by calling toString on the PreparedStatement and copying and pasting it into phpmyadmin and executing it and it worked fine. It just doesn't work through java. Any ideas whats wrong?
By default, you cannot execute multiple statements in one query through JDBC. Splitting it into two calls will work, as will changing the allowMultiQueries configuration property to True.
JDBC Configuration Properties — allowMultiQueries:
Allow the use of ';' to delimit multiple queries during one statement (true/false), defaults to 'false', and does not affect the addBatch() and executeBatch() methods, which instead rely on rewriteBatchStatements.
Default value: false