JPA - My Named Query won't work - java

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)

Related

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.

Executing hibernate template's findByNamedQuery

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?

HQL query join tables

I am using hibernate to connect to my database for a project.
I would like to have a query that gets the products out of my database with the discription and name in a certain language. The parameter I have is the short name for the language, so first I would have to get the id of the language and then get the text in the required languages.
I have tried the following hql query, without success.
from Products as p
where p.productlanguages.languages.shortname like 'eng'
This is an image of the part of the database where the data should come from:
I have got the desired result with an sql query, but I can't seem to get it to work in hibernate. But I would prefer to do this in hql.
SELECT * FROM products p
INNER JOIN productlanguage pl ON pl.Products_id = p.id
WHERE pl.Languages_id =
(
SELECT id FROM languages
WHERE Shortname = 'eng'
);
Could anyone tell me how to build this hql query?
Thank you.
Try below:
from Products p INNER JOIN p.productlanguages pl
where pl.languages.shortname ='eng'
I am assuming that you have mapped Product-Productlanguages relationship as OneToMany and Productlanguages-Langages relationship as ManyToOne as depicted in your E-R diagram.
EDIT: There seems to be a typo in Productlanguage mapping at line public Languages getLanguages() {barcode, remove the barcode in the end.
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="Languages_id", nullable=false, insertable=false, updatable=false)
public Languages getLanguages() {barcode
return this.languages;
}

Convert MySql query to JPA named query

I have a MySql query like this:
select AK.*, max(AA.activityDate)
from AssessmentKey AK
join AssessmentActivity AA on AA.ASSESSMENTKEY_ID = AK.id
group by AK.id having max(AA.activityDate) <= '2012-10-02 17:30:55'
Is there a way to convert into in JPA NamedQuery. I am using OpenJPA.
If I put it directly into:
#NamedQuery(name = "AssessmentActivity.findByDate",
query = "select AK.*, max(AA.activityDate) from AssessmentKey AK
join AssessmentActivity AA on AA.ASSESSMENTKEY_ID = AK.id
group by AK.id having max(AA.activityDate) <= '2012-10-02 17:30:55'")
The error is showed here: select AK.* that identifier expected, got "*" and also it does not like on, here it says:
How can I resolve this problem?
First problem: you should replace AK.* with AK you just need the entity alias here.
Second problem: join syntax is not like that. You should write: join and navigate through the object references,eg: AK.assesmentActivity and use the where keyword instead of on
Here's a tip on join: JPQL join
Remember: you are in the ORM, dealing with Entities and their properties, not DB foreign keys and columns.
(ps: Maybe you wanted to write a NativeQuery? There you can use native SQL syntax)
EDIT:
(on your comment) So you must start your query from AA:
select AK from AssesmentActivity AA join AssesmentKey AK where AA.assesmentKey = AK ...
This way you can join them.

JPA query error

I just started working with the JAVA jpa. So far I only tried the persist method which works.
I am having trouble running the following query
Customer = Customer(manager.createQuery("Select c FROM Customer c where c.LastName=\"Lname\""));
However in the above case my Customer class is not being recognized. Am I doing this right ?
The query object cannot be typecast-ted so I resolved the problem by using
query = em.createQuery( "SELECT c FROM Country c WHERE c.name = 'Canada'");
Country c = (Country)query.getSingleResult();

Categories