Executing hibernate template's findByNamedQuery - java

I'm pretty new to hibernate and I was trying it out in one of my applications. I chose to use annotation session factory bean and my editor generated entity classes for each table from the DB which had named queries. hibernateTemplate.findByAll worked fine. But when I tried hibernateTemplate.findByNamedQuery("findById", "<some_id>"), it gave an error: java.lang.IndexOutOfBoundsException: Remember that ordinal parameters are 1-based. After a bit of googling, tried out multiple solutions:
Changed the namedQuery that was generated by editor from : #NamedQuery(name = "Table.findById", query = "SELECT u FROM Table t WHERE t.id = :id"), to : #NamedQuery(name = "Table.findById", query = "SELECT u FROM Table t WHERE t.id = ?") but got the same error.
Tried using hibernateTemplate.findByNamedParam but ended up getting error: java.lang.IllegalArgumentException: node to traverse cannot be null!
I can use hibernateTemplate.find() to achieve this but how do I use findByNamedQuery/Param methods to achieve the same since the documentation says these methods may be used to fetch records based on a field?

Related

Hibernate : How to get last n rows in spring boot JpaRepository?

Iam working with spring boot and jpa repository I want get the last 2 records from database using hql query.
I have writen the follwoing query but its not working.
#Query("select news from(select news from NewsDTO news order by news.newsId desc limit 2) sub order by news.newsId asc")
It is throwing the folloing exception
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 17 [select news from(select news from com.mer.aigs.dto.news.NewsDTO news order by news.newsId desc limit 2) sub order by news.newsId asc]
JPQL doesn't support LIMIT clause natively. With Spring Data JPA, however, you can use
combination of ORDER BY .. DESC and Pageable to achieve what you intend to. Refer this for detailed information https://www.logicbig.com/tutorials/spring-framework/spring-data/pagination.html
limit keyword is not supported by hql (it's even different across different databases). You need to create a Query using entity manager and specify the maximal size:
em.createQuery("your query").setMaxResults(2).getResultList()
assuming you have entity manager injected:
#Autowired
private EntityManager em
This solution performs better than using Pageable.
As mentioned by #Kedar you cannot use LIMIT inside your JPQL query due to the database-specific nature. Therefore you need to use a NATIVE QUERY and replace the physical table name and column name for NewsDTO and newsId:
#Query(value = "select news from(select news from *NewsDTO* news order by *newsId* desc limit 2) sub order by *newsId* asc", nativeQuery = true)
This worked for me, where created is the timestamp column in the table:
repository.findAll(PageRequest.of(0, 2, Sort.by("created").descending())))
In my case, I wanted the result sorted by the created column.
Hope this helps someone.

no result after transforming postgres query to jpql in spring data jpa

I am trying to write a query to fetch list as this query is native sql query, all I need is to transform to spring jpql in which I am failing badly. if there is any link related to this please let me know
I am supposed to get list from this query. as this query is working fine with postgres console but when I even tried this with spring jpa as native query
it is showing results in console but not fetching in service layer [edit:] I mean not calculating any result set.
I am sure I am missing some important/small thing here.
below is the native postgres query
selcet t.id,count(*), count(*) filter (where t.status = 'DONE') from table t where t.id in ([list]) group by t.id
what Im trying is
SELECT t.id, count(t), count(t.id) where staus = 'DONE' from Table t where t.id in ([list]) group by t.id
edit: with constructor based query this is not even working
I am not even sure how to start this query
while being new to this I am not even able to start how to solve this.
Any hint, insight will be useful

MSSQL Invalid Syntax with Hibernate when using DISTINCT?

So I have this piece of Java code:
final Query query = session.createSQLQuery("SELECT DISTINCT(expense_document.id) FROM expense_document JOIN generic_object ON expense_document.id = generic_object.id JOIN expense_document_item ON expense_document_item.document_id = expense_document.id JOIN generic_object ON expense_document_item.id = generic_object.id WHERE expense_document.client_id = :client_id").setParameter("client_id", client.getId()).setMaxResults(1000);
and when this code is executed I get:
org.hibernate.exception.SQLGrammarException: could not execute query
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near the keyword 'from'.
I can not find what MS SQL does not like about this query. When I am connected to MySQL, this line will not cause any problems.
Try removing the parenthesis around the parameter to the distinct keyword.
Use it like this:
select distinct something from somewhere
Your query looks fine.. are you using an up to date driver for MSSQL?
See how to configure hibernate config file for sql server for supported SQL server drivers.
You should be able to do:
final Query query = session.createSQLQuery("SELECT DISTINCT(expense_document.id) FROM expense_document JOIN generic_object ON expense_document.id = generic_object.id JOIN expense_document_item ON expense_document_item.document_id = expense_document.id JOIN generic_object ON expense_document_item.id = generic_object.id WHERE expense_document.client_id = :client_id").setParameter("client_id", client.getId()).setMaxResults(1000);
or
final Query query = session.createSQLQuery("SELECT DISTINCT expense_document.id FROM expense_document JOIN generic_object ON expense_document.id = generic_object.id JOIN expense_document_item ON expense_document_item.document_id = expense_document.id JOIN generic_object ON expense_document_item.id = generic_object.id WHERE expense_document.client_id = :client_id").setParameter("client_id", client.getId()).setMaxResults(1000);
However, if you're using hibernate, why aren't you using HQL, JPA Query language or Criteria? That should ensure that you don't have to change SQL syntax depending upon the vendor as they differ slightly in different flavours. I feel using JPA with entity manager might be the way forward if you're switching between different databases as createSqlQuery will send the string as native SQL to the vendor.
Hibernate EntityManager implements the programming interfaces and
lifecycle rules as defined by the JPA 2.0 specification
https://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html_single/
If you're using something like hibernate, then createSqlQuery is really good for sending vendor specific queries when you want to set hints for example.

JPA - My Named Query won't work

I am having some problems, with the first time I've gotten into JPA. This is the query I'd like to put in as an #NamedQuery, and this SQL works.
select t1.*, t2.SHORT_NAME from ePluribusWS.GRAPH_ACL t1 join DB_AUTH.USERS t2 on t1.USER_ID = t2.ID where GRAPH_ID = 31611 ;
I'm not sure if this is supported within JPA, since I'm doing a JOIN across different databases, but within the same server. The SQL works fine.
When I try and add this in as a named query (the third one below) I get an error message (Syntax error parsing) that "A path expression cannot end with a comma" which the only Google'ing of shows me JPA source code which generated the error message.
#Entity
#Table(name = "GRAPH_ACL", catalog = "ePluribusWS", schema = "")
#XmlRootElement
#NamedQueries({
.
.
#NamedQuery(name = "EPluribusACLEntryRecord.findByUserId", query = "SELECT g FROM ACLEntryRecord g WHERE g.userId = :userId"),
#NamedQuery(name = "EPluribusACLEntryRecord.findByGraphId", query = "SELECT t1.*, t2.SHORT_NAME FROM ACLEntryRecord t1 JOIN DB_AUTH.USERS t2 ON t1.USER_ID = t2.ID WHERE t1.GRAPH_ID = :graphId"),
#NamedQuery(name = "EPluribusACLEntryRecord.findByCreated", query = "SELECT g FROM ACLEntryRecord g WHERE g.created = :created"),
I'm sort of confused, since it looked like the JPA annotations required that they end with a comma.
Thanks for taking the time to read my question, and provide any insight. Normally, editors remove this "thanks" section, which I think is sort of an unpleasant edit.
A NamedQuery is JPQL, not SQL. There is no "*" and "DB_AUTH.USERS" is an invalid construct in JPQL ... has to refer to entities relative to the candidate entity (the entity defines where its schema is).
If you wanted to refer to tables that are not mapped to entities then you would have to use an SQL query (NamedNativeQuery)

Getting error in joining tables using hibernate

I am trying to join multiple table using hibernate but its not working for me can someone please help me out.
I tried Criteria that was not working then thought of using query even that is not working
My code looks like
final Session session = getSession();
String query = "SELECT r.REFERRER_ID from REFERRAL_PAYMENT_INFO r, SIGNUP_REFERRAL s";
Query q = session.createQuery(query);
List list = q.list();
I am getting this error -
"Caused by: org.hibernate.hql.ast.QuerySyntaxException:
REFERRAL_PAYMENT_INFO is not mapped [SELECT r.REFERRER_ID from REFERRAL_PAYMENT_INFO
r, SIGNUP_REFERRAL s]"
You must use the classes (entities) you mapped in HQL queries. If you want to use normal SQL, then you have to call session.createSQLQuery().
Look at the documentation for hibernate session:
http://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/Session.html

Categories