Can't parse jsonb Operator in JPA - spring

I'm trying to fetch the rows that have at least one matching element in the jsonb array field from an input list. jsobb_column of table_a is a jsonb field that stores values in the form of an array.
The following sql query works correctly:
SELECT *
FROM table_a
where table_a.jsobb_column ?| array['item1', 'item2'];
The JPA query would look like this:
"select distinct table_a.* FROM table_a where table_a.jsonb_column ?| array[?0] "
Since JPA is not able to parse the syntax "?|" used for the jsonb operator, an error is thrown:
nested exception is java.lang.IllegalArgumentException: Mixing of ? parameters and other forms like ?0 is not supported!
I tried two different approaches to solve this problem:
Use "ESCAPE" to escape the "?" character, but it didn't work as expected.
Transfer one part of the query as a string parameter. The JPA query looks like follows:
"select distinct table_a.* FROM table_a where table_a.jsonb_column ?0 "
where the parameter at position 0 is a string variable with the following value:
"?| array['item1', 'item2']"
In this case I receive the following error:
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "$0"
DB: postgresql
Questions:
How to escape the "?|" operator, so that the query will be executed?
Is there another way to build the query to accieve the same result?

I managed to find a solution to fix the query in JPA. The solution was simply to use the function jsonb_exists_any().
The query would look like this:
"select distinct table_a.* FROM table_a where jsonb_exists_any(table_a.jsonb_column, array[?0]) = true "

Related

Correct syntax for table name under Inner Join?

I am a complete beginner to BigQuery, and I am trying to create an inner join between two table names, where the column 'title' is the joining column. I believe my syntax is correct, but I do not know what I am doing wrong when I input the ON clause. Here is my syntax:
SELECT
*
FROM
book-to-film-adaptations.movies.movies_metadata_relevant
JOIN
book-to-film-adaptations.goodreads_books.goodreads_books_relevant_data
ON
movies_metadata_relevant.title = goodreads_books_relevant_data.title
I get this error message: Unrecognized name: movies_metadata_relevant at [8:3]
I have tried it with the full names (book-to-film-adaptations.movies.movies_metadata_relevant), but then I get an error message: "Syntax error: Unexpected keyword TO"
Any suggestions?
Thanks
You need to alias tables and use those like in below example - but in this case you will need
...
...
FROM
`book-to-film-adaptations.movies.movies_metadata_relevant` t1
JOIN
`book-to-film-adaptations.goodreads_books.goodreads_books_relevant_data` t2
ON
t1.title = t2.title
or if join columns have same name (like in your case) you can use below version
...
...
FROM
`book-to-film-adaptations.movies.movies_metadata_relevant` t1
JOIN
`book-to-film-adaptations.goodreads_books.goodreads_books_relevant_data` t2
USING (title)

Optional parameter in query does not work for db2 but works in oracle

Below query works fine for Oracle database, but for Db2 it throws error sqlcode -417.
I have looked up similar problems but did not get any definitive answer:
#Query(value = "select * from tableName f where (aC is null or f.a_c = aC)", nativeQuery = true)
Page<tablename> findByFilters(String aC, Pageable pageable);
On execution the error code is -417
One way to solve this problem would be to rewrite the query as the following:
select * from tableName f where f.a_c = coalesce(aC, f.a_c)
The form of query above is likely to be accepted. In order to find out the exact reason of the error you get, it is necessary to trace the actual SQL statement passed to Db2.
Another option of solving the problem may be to add the CAST operator, which would define the data type of your parameter:
select * from tableName f where (cast(aC as integer) is null or f.a_c = aC)
This is suggested in the description of the error you get

Parametrizing a sub query with jdbc PreparedStatement

I have the following query where the first argument itself is a subquery
The java code is:
String query = select * from (?) where ROWNUM < ?
PreparedStatement statement = conn.preparedStatement(query)
statement.setString(1, "select * from foo_table")
statement.setInt(2, 3)
When I run the java code, I get an exception. What alternatives do I have for making the first subquery statement.setString(1, "select * from foo_table") a parameter?
This is not possible, parameter placeholders can only represent values, not object names (like table names, column names, etc) nor subselects or other query elements.
You will need to dynamically create the query to execute using string concatenation, or other string formatting/templating options.

getting Hibernate error when using DBMS_RANDOM.value

I would like to achieve same result as the below query using Hibernate SQL, i.e., I would like to get two random records from the table whose ID is not equal to 300. I am using Hibernate 4.1 and Oracle 11g. I ran the below query on Toad and it gives 2 random records. But, when I try to run the HQL, there is error to do with the usage of "DBMS_RANDOM.value".
SELECT * FROM
( SELECT *
FROM table
where ID != '300'
AND q_ID=125
ORDER BY DBMS_RANDOM.value
)WHERE rownum < 3
;
I tried creating criteria and query, but both give Hibernate errors:
Hibernate Message: Invalid path: 'DBMS_RANDOM.RANDOM' [from com.model.table tab where tab.ID != '33092' ORDER BY DBMS_RANDOM.RANDOM]
and my actual hibernate query is:
Query query = session.createQuery("from table tab where tab.ID != '" +agrmId+"' ORDER BY DBMS_RANDOM.RANDOM").setMaxResults(2);
I also tried ORDER BY rand() and that gives an Oracle error.
Thank you for any help.
I solved the problem by adding a property tag in the hibernate mapping file:
<property name="constVal" formula="DBMS_RANDOM.RANDOM" type="long"/>
and then, in the POJO class, I added a variable with getter and setter methods:
private long constVal;
then, in the DAO class, I added the following query:
Criteria crit1 = session.createCriteria(table.class);
crit1.add(Restrictions.ne("id",300));
crit1.add(Restrictions.eq("quesId",125));
crit1.addOrder(Order.asc("constVal"));
crit1.setMaxResults(2);
and that solved it.

Set array of values to SQL query

I'm using JDBC, I have to set array of values to a single column,
I know it works in Hibernate and Ibatis but it seems to be hard to get it working Pure JDBC sql.
I have an array of String values
names[] = new String[]{"A","B","C"};
and a Query like
select * from emp where name in(?)
I tried pstmt.setObject(1,names), it is not working..
This is not supported in pure JDBC. You have to generate a query so that the in clause contains one placeholder for each element of the array.
Spring's JDBC helper classes support named parameters and what you want to do.
This will work with the following Syntax:
"SELECT * FROM emp WHERE name IN ( SELECT column_value FROM TABLE( ? ) )"
pmst.setArray( 1, conn.createArrayOf( "VARCHAR", names ) );

Resources