JPA Query does not work - java

Can you help me please with this problem? I want use this method for find the specific nick in my database (It made with Apache Derby). I have used the EntityManager and mapping Persistence - Entity classes from database in the NetBeans.
public static boolean findByNick(String nick) {
List<eng.db.User> ret;
EntityManager em = getEntityManager();
Query q = em.createQuery("SELECT * FROM User u WHERE u.nick =:nick");
q.setParameter("nick", nick);
ret = q.getResultList();
em.close();
boolean hodnota = false;
if (ret.isEmpty()) {
hodnota = true;
}
return hodnota;
}
I get this error:
java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:
Exception Description: Syntax error parsing [SELECT * FROM User u WHERE u.nick =:nick)].
[21, 21] A select statement must have a FROM clause.
[7, 7] The left expression is missing from the arithmetic expression.
[9, 20] The right expression is not an arithmetic expression.
[41, 42] The query contains a malformed ending.
Where is the problem please?

If nick is the primary key of your entity (#Id), then use:
return em.find(eng.db.User, nick) != null;
Or if not:
Query q = em.createQuery("SELECT TRUE FROM User u WHERE u.nick =:nick");
q.setParameter("nick", nick);
return !q.getResultList().isEmpty();
By returning a simple boolean, you minimize the DB response.

It should be
UPDATE
according to your comment now the query should be:
SELECT u.userID, u.enterKey, u.nick
FROM User u
WHERE u.nick = ?
or with named param
SELECT u.userId, u.enterKey, u.nick
FROM User u
WHERE u.nick = :nick
where usereID, enterKey and nick are fields(properties) of your entity type User.
Your User class should look pretty much like this
#Entity
public class User {
#Id
private long userId;
#column(name="EnterKey"
private String enterKey;
#column(name="nick")
private String nick;
// setter getter
}
Regard that this hql and you use the class and property names of the object model which you defined as arguments for the query.
in your query Hibernate or any other JPA implementation creates a list of objects of type User using the mapping you defined. The expression * can not be associated with an object name of this type. The equivalent to * in sql is in object related query languages just the of the alias of the from clause in your case "u" since the from clause looks like this:
From User u
If you want just to select separate fields of your Entity you have to declare
Select alias.property
from Entity alias
or in your special case
Select u.nick
From User u
In this case instances of type User are created and the field nick is set.

Related

Getting empty result from the #Query in Hibernate

I am using Hibernate to execute my query, in admin panel i am getting correct result but while using in Hibernate it is not giving any result.
Dao layer -
#Query("select new com.eventila.pms.entity.ReferenceLead(projectId,count(lm)) from LeadMaster lm where lm.vendorId= ?1 and lm.source = 'share' group by lm.projectId")
List<ReferenceLead> getReferenceByUser(String userId);
Pojo -
#lombok.Data
#JsonInclude(JsonInclude.Include.NON_NULL)
public class ReferenceLead {
String projectId;
Long referenceLead;
Long count;
protected ReferenceLead(){}
public ReferenceLead(String projectId,Long count) {
this.projectId=projectId;
this.count=count;
}
}
After executing this i am getting a empty list.
Please help me out.
In your select query return the fields without calling new constructor:
#Query("select projectId, count(lm) from LeadMaster lm where lm.vendorId = ?1 and lm.source = 'share' group by lm.projectId")
List<ReferenceLead> getReferenceByUser(String userId);
Hibernate will instantiate the object using these fields. Also, add #Entity annotation to your ReferenceLead class.
'source' is the keyword in SQL.
It is a keyword used in MERGE. i.e. WHEN NOT MATCHED BY SOURCE.
The word MATCHED also exhibits the same behaviour in that it gets highlighted grey in the editor.
Neither of these are reserved keywords though so if used as an identifier they do not need to be delimited (unless you find the syntax highlighting distracting).

JPA Query Missing alias and column (Hibernate)

I have the following relevant JPA annotated classes in a Spring-Boot JPA enabled project (All Groovy Code):
#Entity
abstract class Character {
#Id
String id;
String name;
#ElementCollection(targetClass = Episode)
#Enumerated(EnumType.ORDINAL)
Collection<Episode> appearsIn;
}
#Entity(name = "Human")
public class Human extends Character {
String homePlanet;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "favorite_droid_id")
Droid favoriteDroid;
}
public enum Episode {
PHANTOM_MENACE,
ATTACK_OF_THE_CLONES,
REVENGE_OF_THE_SITH,
A_NEW_HOPE,
EMPIRE_STRIKES_BACK,
RETURN_OF_THE_JEDI,
THE_FORCE_AWAKENS
}
When I attempt to execute the following JPA Query:
def query = em.createQuery("from Human h where h.appearsIn in (:episodes)");
query.setParameter("episodes", EnumSet.of(Episode.THE_FORCE_AWAKENS));
def result = query.getResultList();
The generated SQL statement does not seem to have the alias to the Character table or the column name for appears_in:
select human0_.id as id2_0_, human0_.name as name3_0_, human0_.favorite_droid_id as favorite6_0_, human0_.home_planet as home_pla5_0_
from character human0_
cross join character_appears_in appearsin1_
where human0_.dtype='Human' and human0_.id=appearsin1_.character_id and (. in (?))
I have also tried using equals instead of in, with the same behavior:
from Human h where h.appearsIn = :episode
Produces the following SQL:
select human0_.id as id2_0_, human0_.name as name3_0_, human0_.favorite_droid_id as favorite6_0_, human0_.home_planet as home_pla5_0_
from character human0_
cross join character_appears_in appearsin1_
where human0_.dtype='Human' and human0_.id=appearsin1_.character_id and .=?
Any help is greatly appreciated.
Your query is invalid - as #Neil Stockton pointed out, by writing h.appearsIn in (:episodes) you are saying "collection in collection" which does not make sense.
You should rather declare a "collection member variable" like this:
select distinct h
from Human h
join h.appearsIn ai
where ai in (:episodes)
ai represents a single element of appearsIn (like an iterator).

DOT node with no left-hand-side using HQL with join

I am trying to find the maximum value of a Date column in mySQL DB using hibernate query language with join
#Query("select o.techid, CAST(MAX(o.last_modified) AS DATE)
from com.dw.model.user.User as u
left join com.dw.model.order.Order as o
on u.username=o.techid group by o.techid")
List<User> findUsers();
Model class =
#Entity(name = "orders")
#Scope("prototype")
#Component
#JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
public class Order {
#Id
private long orderNumber;
private Date last_modified;
I am getting this error :-
Caused by: java.lang.IllegalStateException: DOT node with no left-hand-side!
Can anyone please help me out by telling me how to write this in Hibernate?
Remove your package names. An entity is defined by its name only. Dots are used for properties and links between tables (when defined as a #ManyToOne* property).
select o.techid, CAST(MAX(o.last_modified) AS DATE)
from User as u
left join Order as o
on u.username=o.techid group by o.techid
Think Classes and Properties, not columns, when you write HQL.
Try following solution, this should work
SELECT o.techid, CAST(MAX(o.last_modified) AS DATE)
FROM User u LEFT JOIN u.order o GROUP BY o.techid

Querying more than two entities

JPQl Am new in jpa and I want to query all fields from two entities and then use the entity classes getters to access the data .
Query q = em.createQuery("SELECT u(*),f(*) FROM User u join Employee f in u.empid=f.id WHERE u.username = :login AND u.passowrd = :pass");
q.setParameter("login", usernameTextField.getText().trim());
q.setParameter("pass", passwordPasswordField.getText().trim());
Error
Exception [EclipseLink-0] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b):
org.eclipse.persistence.exceptions.JPQLException
Exception Description: Syntax error parsing [SELECT u(),f() FROM User u join Employee f in u.empid=f.id WHERE u.username = :login AND u.passowrd = :pass].
[9, 9] The left expression is missing from the arithmetic expression.
[10, 10] The right expression is missing from the arithmetic expression.
[15, 15] The left expression is missing from the arithmetic expression.
[16, 16] The right expression is missing from the arithmetic expression.
[7, 8] The SELECT clause has 'u' and '()' that are not separated by a comma.
[13, 14] The SELECT clause has 'f' and '()' that are not separated by a comma.
[56, 57] The FROM clause has 'User u JOIN Employee f IN u.empid=' and 'f.id ' that are not separated by a comma.
[46, 57] The expression is invalid, which means it does not follow the JPQL grammar.
[62, 62] An identification variable must be provided for a range variable declaration.
Thank you all for your contributions......so far I have amended the query up to this
SELECT u,f
FROM User u, Employee f
WHERE u.username = :login AND u.passowrd = :pass AND u.empid=f.id
and now I am getting this error
internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 '.id))' at line 1
Error Code: 1064
Call: SELECT t0.id, t0.level, t0.passowrd, t0.username, t0.empid, t1.id, t1.address, t1.email, t1.gender, t1.idnum, t1.name, t1.phone, t1.staffcol, t1.dept FROM user t0, staff t1 WHERE (((t0.username = ?) AND (t0.passowrd = ?)) AND (t0.empid = t1.id.t1.id))
bind => [2 parameters bound]
Query: ReportQuery(referenceClass=User sql="SELECT t0.id, t0.level, t0.passowrd, t0.username, t0.empid, t1.id, t1.address, t1.email, t1.gender, t1.idnum, t1.name, t1.phone, t1.staffcol, t1.dept FROM user t0, staff t1 WHERE (((t0.username = ?) AND (t0.passowrd = ?)) AND (t0.empid = t1.id.t1.id))")
Question already asked:
JPA: Query that returns multiple entities
(In this example it's hibernate what is an implementation von jpa)
Maybe something like this:
Query q = em.createQuery("SELECT u, f FROM User u, Employee f WHERE u.empid = f.id and u.username = :login AND u.passowrd = :pass");
q.setParameter("login", usernameTextField.getText().trim());
q.setParameter("pass", passwordPasswordField.getText().trim());
Object[] result = (Object[]) q.getSingleResult();
User user = result[0];
Employee emp = result[1];
edit: This part of your translated query looks like you have a mapping problem in your Employee class:
... t1.id.t1.id ...
I think you can't do such a thing and here is why.
The query you post is "inspired" by the relational approach, i.e. you query for a table with arbitrary fields (maybe produced by the join and maybe even artificial).
JPA is by nature is an ORM framework - which means it encapsulates a relation structure by wrapping it in Object.
So, you have to work with Objects as its common in relational data world.
This means that you always should query for an object.
Now how about the join you've mentioned?
Actually join is a way to get a projection in relational data modeling world, again its not for object oriented world, here we operate with inheritance and composition.
You may model the same relation with these mentioned above.
So in object based data modeling world you should think about the "relation" between user and employee as like these are objects and not different tables - think as a object oriented language programmer and not an sql user.
In this particular case my first bet would be saying that a user 'is an' employee with some additional information (I might be wrong its more a question of data modeling, it might be an opposite, so you should think about this).
So you define class Employee in java
then you define class User in java:
class Employee {
}
class User extends Employee {
}
And then you provide a relational mapping to this hierarchy of objects.
There are 3 different strategies for mapping such a thing, you might be interesting on reading this
Hope this helps
I am not expert but I assume:
Make your return type main entity like following.
public User methodWhichReturnsListAfterQuery(){
Query q = em.createQuery("SELECT u FROM User u join u.employee f WHERE u.empid=f.id AND u.username = :login AND u.passowrd = :pass");
q.setParameter("login", usernameTextField.getText().trim());
q.setParameter("pass", passwordPasswordField.getText().trim());
return (User)query.getSingleResult();
}
I assume your main entity is User
Your User entity like following:
public class User Implements Serializable{
.
.
//Some relation type
private Employee employee;
.
.
//getter() and setter()
}
get values after query
User user= methodWhichReturnsListAfterQuery ();
Now you can get values like this:
String userName=user.getUserName();
String password=user.getPassword();
String name=user.getEmployee().getName();
Long departMentId=user.getEmoloyee().getDepartmentId();
Hope you get...

Writing a Hibernate Criteria API Query with restrictions for multiple sub-elements

I have a data model that looks like this (simplified example):
public class Address { private List<AddressLine> addressLines; }
public class AddressLine { private String value; private String type; }
I am trying to use the Criteria API to search for Addresses in the database that contain specific combinations of AddressLines. For example, to retrieve all addresses that contain the address lines {(type="CITY", value="London"), (type="COUNTRY", value="GB")}. I haven't been able to find any examples of such a query.
As far as I have been able to get is to query for an Address based on a single AddressLine.
session.createCriteria(Address.class)
.createCriteria("addressLines")
.add(Restrictions.and(Restrictions.eq("type", type), Restrictions.eq("value", value))).list()
If I add a restriction for a second address lines the SQL that hibernate generates is basically asking SELECT x WHERE x.y = 'a' AND x.y = 'b' so will never return any results.
I have found similar questions being asked before but none of them have an accepted or voted for answer.
You need to write the Criteria equivalent of
select a from Address a where
exists (select line1.id from AddressLine line1 where line1.address.id = a.id
and line1.type = 'CITY'
and line1.value = 'London')
and exists (select line2.id from AddressLine line where line2.address.id = a.id
and line2.type = 'COUNTRY'
and line2.value = 'GB')
This means writing a DetachedCriteria for each subquery, with an id projection, and using these detached criterias as argument of two Subqueries.exists() calls. The alias of the address entity in the main criteria can be used in the detached criterias to implement the line1.address.id = a.id restriction.

Categories