Apache Ignite : Not able to query Select...in() clause with spring boot - ignite

I am not able to use IN() clause with apache ignite using spring-boot.
I have tried two ways but both are not working.
Please help me to solve the issue.
repository:
#RepositoryConfig(cacheName = "test")
public interface TestRepo extends IgniteRepository<Test, TestKey>{
#Query("SELECT distinct subscribers FROM test where city in :cities")
List<Integer> selectAll(#Param("cities") List<String> cities, Pageable pageable);
List<Test> findByCityIn( List<String> cities);
error:
org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "SELECT ""test"".""TEST""._KEY, ""test"".""TEST""._VAL FROM TEST WHERE ((TEST.CITY IN ?[*])) "; expected "("; SQL statement:
SELECT "test"."TEST"._KEY, "test"."TEST"._VAL FROM Test WHERE ((Test.city IN ?)) [42001-196]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) ~[h2-1.4.196.jar:1.4.196]
at org.h2.message.DbException.getSyntaxError(DbException.java:205) ~[h2-1.4.196.jar:1.4.196]

SELECT "test"."TEST"._KEY, "test"."TEST"._VAL FROM Test WHERE ((Test.city IN ?))
First of all, question mark should definitely be in parens: IN (?).
Second, you are trying to bind multiple values (in list) to the same question mark at once. I'm not sure that will work. Docs tell that it won't work for IN but would for the case described below.
Third, using IN with Ignite is not recommended for performance reasons, and using join table() is suggested instead:
https://apacheignite-sql.readme.io/docs/performance-and-debugging#section-sql-performance-and-usability-considerations

Related

How to create query with Spring Data JPA?

Please help me. I can not create query from native sql using spring data.
How do I convert the following expression?
select distinct brand, model from cars
where brand like '%:query%' or model like '%:query%' limit 2;
You could use projections with Spring Data JPA, something of the likes of:
interface SimpleCar {
String getBrand();
String getModel();
}
and then:
List<SimpleCar> findDistinctByBrandLikeOrModelLike(String query);
You can review here for different options to query a DB with some examples.
By the way, if you want to see what queries your methods are executing you can activate DEBUG logging mode in log4j for org.springframework package or org.hibernate (if you're using Hibernate)
that helped me, hopefully you too
https://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-three-custom-queries-with-query-methods/
Use:
#Query("select distinct brand, model from cars " +
"where brand like %:query% or model like %:query% limit 2")
public List<Car> find(#Param("query") String query);
Basically what you had but without the speech marks.

Blank FROM clause in JPQL?

I'm using a JPQL select to access a Oracle DB function: select FUNCTION('function_name', 'foo', 1234) from com_mycompany_bar obj
This works as expected and the function is indeed called. The thing is I actually don't need the FROM clause and would rather have it empty instead of having to access an entity just to conform to the syntax.
What is the best option I have here?
I see several possible answers:
Within standard JPA there are two options, both involving Oracle DUAL "table"
Map DUAL to an entity and use it in the FROM clause. It is the more "JPQL" way, but it is more involved:
In Java code:
#Entity(name = "Dual")
#Table(name = "SYS.DUAL")
public class Dual {
#Id
#Column(name = "DUMMY")
private String dummy;
}
In orm.xml:
<named-query name="yourQuery">
<query><![CDATA[
SELECT FUNCTION('function_name', 'foo', 1234) FROM Dual d
]]>
</query>
</named-query>
In client code:
Query q = entityManager.createNamedQuery("yourQuery");
Just use a native query that uses DUAL
In orm.xml:
<named-native-query name="yourQuery">
<query><![CDATA[
SELECT function_name('foo', 1234) from sys.dual
]]>
</query>
</named-native-query>
In client code:
Query q = entityManager.createNativeQuery("yourQuery");
As a last option, you can use some JPA implementation extension to JPA and avoid DUAL:
Eclipselink:
http://wiki.eclipse.org/EclipseLink/Examples/JPA/StoredProcedures
http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_namedstoredprocedurequery.htm
http://ronaldoblanc.blogspot.com.br/2012/05/jpa-eclipselink-and-complex-parameters.html
Hibernate:
http://objectopia.com/2009/06/26/calling-stored-procedures-in-jpa/
jpa calling stored procedure with output cursor
How to call Oracle Function or Procedure using Hibernate 4 (EntityManager) or JPA 2
In short: I don't think it's possible to skip FROM clause of JPQL query.
JPQL grammar requires FROM clause to be present (see e.g. here or here).
Calling stored procedures/functions is typically done via native queries (see: createNativeQuery). So this should work:
em.createNativeQuery("select function_name('foo', 1234)").getSingleResult()
UPDATE (from comments):
That's true that JPA native queries don't support named parameters. So you must decide which is the lesser of two evils for you: either using JPQL with unnecessary entity reference or native query with positional parameters instead of named.
But be aware that FUNCTION is EclipseLink extension so it won't work should you decide to change a vendor.

How to use a dynamic parameter in a IN clause of a JPA named query?

my problem is about this kind of query :
select * from SOMETABLE where SOMEFIELD in ('STRING1','STRING2');
the previous code works fine within Sql Developer.
The same static query also works fine and returns me a few results;
Query nativeQuery = em.createNativeQuery(thePreviousQuery,new someResultSet());
return nativeQuery.getResultList();
But when I try to parameterize this, I encounter a problem.
final String parameterizedQuery = "select * from SOMETABLE where SOMEFIELD in (?selectedValues)";
Query nativeQuery = em.createNativeQuery(parameterizedQuery ,new someResultSet());
nativeQuery.setParameter("selectedValues","'STRING1','STRING2'");
return nativeQuery.getResultList();
I got no result (but no error in console).
And when I look at the log, I see such a thing :
select * from SOMETABLE where SOMEFIELD in (?)
bind => [STRING1,STRING2]
I also tried to use no quotes (with similar result), or non ordered parameter (:selectedValues), which leads to such an error :
SQL Error: Missing IN or OUT parameter at index:: 1
I enventually tried to had the parentheses set directly in the parameter, instead of the query, but this didn't work either...
I could build my query at runtime, to match the first (working) case, but I'd rather do it the proper way; thus, if anyone has an idea, I'll read them with great interest!
FYI :
JPA version 1.0
Oracle 11G
JPA support the use of a collection as a list literal parameter only in JPQL queries, not in native queries. Some JPA providers support it as a proprietary feature, but it's not part of the JPA specification (see https://stackoverflow.com/a/3145275/1285097).
Named parameters in native queries also aren't part of the JPA specification. Their behavior depends on the persistence provider and/or the JDBC driver.
Hibernate with the JDBC driver for Oracle support both of these features.
List<String> selectedValues = Arrays.asList("STRING1", "STRING2");
final String parameterizedQuery = "select * from SOMETABLE where SOMEFIELD in (:selectedValues)";
return em.createNativeQuery(parameterizedQuery)
.setParameter("selectedValues", selectedValues)
.getResultList();
Instead of:
nativeQuery.setParameter("selectedValues", params);
I had to use:
nativeQuery.setParameterList("selectedValues", params);
This worked for me in derby. parameter without "()".
List<String> selectedValues = Arrays.asList("STRING1", "STRING2");
final String parameterizedQuery = "select * from SOMETABLE where SOMEFIELD in
:selectedValues";
return em.createNativeQuery(parameterizedQuery)
.setParameter("selectedValues", selectedValues)
.getResultList();
Replace this:
nativeQuery.setParameter("selectedValues","'STRING1','STRING2'");
with
List<String> params;
nativeQuery.setParameter("selectedValues",params);
I also faced the same issue.
This is what I did:
List<String> sample = new ArrayList<String>();
sample.add("sample1");
sample.add("sample2");
And now you, can set the sample in params.

org.hibernate.exception.SQLGrammarException: could not execute query?

I got this exception when i try to get the list using NamedQuery:
org.hibernate.exception.SQLGrammarException: could not execute query
Below I mentioned code:
Entity Class Code:
#Table(name = "tbl_users")
#XmlRootElement
#NamedQueries({#NamedQuery(name = "TblUsers.findAll", query = "SELECT t FROM TblUsers t")});
DAO implement Code:
org.hibernate.Query query = session.getNamedQuery("TblUsers.findAll");
List list = query.list();
Please provide solution for this exception.
Was facing same issue for a while and figured out that the problem was due to the Table name being different from the class(or Entity) name in the database. Added the #Table(name = actual_table_name) annotation and it worked.
Get the SQL query that Hibernate is generating (using hibernate.show_sql or, preferably, Hibernate's SQL logging), and execute it against the database yourself. That will most likely help steer you in the right direction.
Try this one it could work.
It Perfectly worked for me.
1) Class level annotation.
#NamedQuery(name="UserDetails.byId" , query="from UserDetails where userId = ?")
2) Get record using NamedQuery
Query qry2 = sf.getCurrentSession().getNamedQuery("USER_DETAILS.byName") ;
qry2.setString(0, "Angad Bansode");
List<UserDetails> user = qry2.list();
for (UserDetails userDetails : user) {
System.out.println("User Details by named native query name = " + userDetails.getUserName() + ", aadhaar no = " + userDetails.getAadharNo());
}
seems like this question is little old but any way once i added below line to hibernate config files it worked for me.
<property name="show_sql">true</property>
For me it was missing access to sequence for auto-increment primary key. After adding this error was resolved.
GRANT USAGE, SELECT ON ALL
SEQUENCES IN SCHEMA public
TO "${user-name}";;

SQl Query to Hibernate Query

I have a MySQL query that I use to retrieve random rows from a table. The query is:
SELECT * FROM QUESTION WHERE TESTID=1 ORDER BY RAND() LIMIT 10;
Now I need to change this query to Hibernate. Did a bit of googling but couldn't find the answer. Can someone provide help on this?
The random function is different between each underlying DB and is not a standard part of SQL92.
Given that you will need to implement a SQLDialect for the given database type you are using.
eg:
class PostgresSQLDialect extends org.hibernate.dialect.PostgreSQLDialect {
PostgresSQLDialect() {
super()
registerFunction( "rand", new NoArgSQLFunction("random", Hibernate.DOUBLE) );
}
}
Then you will need to define that dialect in the config
hibernate {
dialect='com.mycompany.sql.PostgresSQLDialect'
}
According to this post, you can do that :
String query = "from QUESTION order by newid()";
Query q = session.createQuery(query);
q.setMaxResults(10);
Not sure if it will work (especially for the random part), but you can try it :)