Querying by inherited property - java

i am trying to do my first steps in Java, and i am blocked with the next problem: i have this hieararchy class "User -> Traveller".
#Entity
#Inheritance(strategy=InheritanceType.JOINED)
public class User {
// Some properties and accessors.
}
#Entity
#PrimaryKeyJoinColumn(name="user_id")
public class Traveller extends User{
// Some properties and accessors.
}
So, i need search a traveller by your username which is a User class property. I try this in my TravellerDao:
public Traveller findByUsername(String username){
EntityManager em = PersistenceHelper.getEm();
TypedQuery<Traveller> query = em.createQuery("FROM Traveller WHERE username = ?1", Traveller.class);
query.setParameter(1, username);
return query.getSingleResult();
}
But, a javax.persitence.NoResultException is catched. Where is the problem ? In the "where" clausule ? In the join ?. Any ideas ?
Notes:
1) The hierarchy works fine with "find" method. And the database is generated correctly.
2) I have an entry in the Traveller table that links up to one in User table.
3) In the database exists an user with the username that i am using to test.
4) The method get correctly the "username" parameter.
EDIT: Now works. The problem was the execution order of test cases. The query works fine.

I think your query is incorrect, I believe you are forced to name an alias for every entity you want to interact with. Have you tried this?
"SELECT t FROM Traveller t WHERE t.username = ?1", Traveller.class
Also you should have to cast the result when you call query.getSingleResult(). Because you pass in Traveller.class into the createQuery call which is paramaterized by Class<T> resultClass
Edit: Added a 1 after the ? as shown here. http://www.objectdb.com/java/jpa/query/parameter#Ordinal_Parameters_index_
public Country getCountryByName(EntityManager em, String name) {
TypedQuery<Country> query = em.createQuery(
"SELECT c FROM Country c WHERE c.name = ?1", Country.class);
return query.setParameter(1, name).getSingleResult();
}

Related

Named param not being detected

I have a simple query as follows. I get the expected result if I hard code the id value as follows. But it throws IllegalArgumentException exception if I try to get the value from the Param instead. Note that I have tried to use the Param as both long and String and still the same results. Please advise what I am doing wrong. Thanks.
My Query
public interface FeedDetailRepository extends JpaRepository<FeedDetail, Long> {
#Query("select fd.message from FeedDetail as fd where fd.feedId =: id")
String custom(#Param("id") long id);
}
At Controller, if I run the following, I get an exception.
#GetMapping("/something/{id}")
public String getDetail(#PathVariable long id){
return feedDetailRepository.custom(id);
}
But if I hard code the id value as follows, I get the wanted result.
public interface FeedDetailRepository extends JpaRepository<FeedDetail, Long> {
#Query("select fd.message from FeedDetail as fd where fd.feedId = 4")
String getDetailBasedOnFeedId(#Param("id") long id);
}
The exception
nested exception is java.lang.IllegalArgumentException:
org.hibernate.QueryException: Named parameter not bound : id
I would change
#Query("select fd.message from FeedDetail as fd where fd.feedId =: id")
To (difference lies in space)
#Query("select fd.message from FeedDetail as fd where fd.feedId = :id")
This is a small difference for you but big for Spring. He recognizes a parameter by attaching name to colon like that
:id
For more details refer to the official Spring Data JPA Reference.
I had the same issue:
Wrong query:
SELECT * FROM `cars` as c where c.driver_one = :id OR c.driver_two = **:id;**
Correct query:
SELECT * FROM `cars` as c where c.driver_one = :id OR c.driver_two = **:id**
This is likely because of the way you have provided space with in the query.
My suggestion would be to format the code and in the string quotes use something similar
SELECT fd.message from FeedDetail AS fd where fd.feedId = :id

Query not giving solution in DAO class

when i run my query in database visualizer its working perfectly, but i think there are some issues in syntax when i convert it in my DAO class method.
I want to get whole data against the name provided
In Visualizer:
SELECT first_name,last_name,nic,phone,email FROM x_hr_user where (first_name = 'Irum');
Now in Dao
public List<XHrUser> findXHrUserByNameInTable()
{
String name ="Irum";
Query query = em.createQuery("SELECT xHrNewUserObj.firstName,xHrNewUserObj.lastName, xHrNewUserObj.nic, xHrNewUserObj.phone, xHrNewUserObj.emil FROM XHrUser xHrNewUserObj where (xHrNewUserObj.firstName) = (name)");
List<XHrUser> list = query.getResultList();
return list;
}
Instead of showing single row, it displays whole data Table
Thank you
Your current query is not valid JPQL. It appears that you intended to insert the raw name string into your query, which could be done via a native query, but certainly is not desirable. Instead, use a named parameter in your JPQL query and then bind name to it.
String name = "Irum";
Query query = em.createQuery("SELECT x FROM XHrUser WHERE x.firstName = :name")
.setParameter("name", name);
List<XhrUser> list = query.getResultList();
You have to write query as below. where : is used for variable
Query query = em.createQuery("SELECT xHrNewUserObj.firstName,xHrNewUserObj.lastName, xHrNewUserObj.nic, xHrNewUserObj.phone, xHrNewUserObj.emil FROM XHrUser xHrNewUserObj where (xHrNewUserObj.firstName) = :name");

Update query not working propertly using namedquery in jpa

I'm trying to update a simple table using jpa. I have written a jpa namedquery for it
#NamedQuery(name="updatedetails",query="update myentity set enddesc=?, startdesc=? Where id=?")
My code is as follows
em.createNamedQuery("updatedetails",myentity.class).serParameter(1, "abcd").serParameter(2,"gjvg").serParameter(3, "gghjj").executeUpdate();
myentity is my class name
It throws me the following error
Encountered "=" at character but expected ["."] While parsing the query
Is there anything wrong with the query
I believe that JPA named queries should use actual names are parameter placeholders, rather than ?, the latter which is used in prepared statements. So something like this should work:
#NamedQuery(name="updatedetails",query="update myentity set enddesc = :enddesc, startdesc = :startdesc Where id = :id")
List<myentity> results = em.createNamedQuery("updatedetails", myentity.class)
.setParameter("enddesc", "abcd")
.setParameter("startdesc", "gjvg")
.setParameter("id", "gghjj")
.getResultList();
As side note, you should probably make your class names begin with uppercase letters, i.e. call it MyEntity, rather than what you currently have.
em.createNamedQuery("updatedetails",myentity.class).serParameter(1, "abcd").serParameter(2,"gjvg").serParameter(3, "gghjj").executeUpdate();
Instead of serParameter use setParameter, should work.
write this code in model class
#NamedQuery(name = "new_ticket_bat.UpdateflagAutres", query = "UPDATE new_ticket_bat t set t.status_AUTRE='0' WHERE t.id= :id")
<br>
write this code in you service class
static void updateflagAutres(String id) {
DataBaseTools dbTools = new DataBaseTools("databaseOv");
try {
Query q=dbTools.em.createNamedQuery("new_ticket_bat.UpdateflagAutres");
q.setParameter("id", id);
q.executeUpdate();
dbTools.em.getTransaction().commit();
dbTools.em.close();
} catch (Exception ex) {
ex.printStackTrace();
Tools.traiterException(Tools.getStackTrace(ex));
}
}

Relationships between JPQL, Java (and the Oracle DB)

I am confused about the above relationship.
My Oracle DB Tables:
xd_Users: user_id (pk), client_id (fk), name, doj, email, dol
xd_Managers: manager_id (pk), user_id (fk)
Corresponding Java Entities User and Manager relate to the above two tables respectively. Manager and User are separate, not related by inheritance, and have fields that correspond to the DB tables.
In my application, a Manager has to be a User.
I am writing the a(n as yet unfinished) method (in a class called PersistService) to retrieve a list of users who are managers.
public static ArrayList<User> getManagersForClient(Client client) {
Long clientId = client.getClientId();
EntityManager em = getEntityManager();
String sqlQuery = "SELECT u FROM XD_USERS u, XD_MANAGERS m WHERE u.CLIENT_ID = :clientId";
TypedQuery<User> query = em.createQuery(sqlQuery, User.class);
query = query.setParameter("clientId", clientId);
ArrayList<User> clientUsers = (ArrayList<User>) query.getResultList();
for (User user : clientUsers) {
}
return clientUsers;
}
The pseudo-sql query I constructed was (:client_id at the end is just the java variable, hence the pseudo-sql):
select * from users u join managers m on u.user_id = m.user_id where u.client_id = :client_id;
I am having trouble converting this to a valid JPQL query. I don't understand how to think about solving this. In particular, the relationship between the identification variable, the single-valued relationship field, the collection-valued relationship field and the persistent field is very confusing. And I am even more confused by this post. Please help!
If you have coded the related entities correctly then your sql select query is something like this in jpql (according to the structure of related tables you gave):
select u.userId,u.name,u.doj,u.email, u.dol, m.managerId
from User u
join u.manager m
where u.clientId = :client_id;

How to retrieve a member object of a class using Hibernate?

Using following code I can successfully retrieve address fields of a user, to do that I need to define all its fields using Projection. Imagine address has 100 fields, in this case I have to define all of them.
I am wondering if I can return just address object of customer without defining all its fields in Proposition?
I know I can retrieve id of address and use that to retrieve its object, but I am wondering if there is ano other method rather than this or defining all its fields.
Hibernate
.....
Criteria cre = session.createCriteria(User.class, "user")
.createAlias("user.address", "addr");
cre.add(Restrictions.eq("user.id", ID));
ProjectionList pl = Projections.projectionList();
pl.add(Projections.property("addr.id").as("id"));
pl.add(Projections.property("addr.unit").as("unit"));
.......
cre.setProjection(pl);
Address address = (Address) cre.list().get(0);
I used the following as well but it runs into error (could not resolve property: addr of: com.myProject.User)
pl.add(Projections.property("addr").as("address"));
Java
#Entity
public Class User {
#Id
#GeneratedValue
private long id;
#OneToOne
private Address address;
...
}
Use JPQL/HQL:
select a from User u join u.address a where u.id = :userId
The Criteria API is more limited than JPQL, and can't select any other entity than the root entity. It shouldn't be used if the query doesn't have to be dynamically composed. Of course, if the association is bidirectional, you can simply use
select a from Address a where a.user.id = :userId
or its equivalent Criteria:
Criteria c = session.createCriteria(Address.class, "a");
c.createAlias("a.user", "u");
c.add(Restrictions.eq("u.id", userId));
If the result you pull in from a query will match the fields of a DAO you have defined. I would just type-cast the result from an hql or native SQL query.
Select *
From Address a
where a.id = :userid
Address addrObject = (Address) query.uniqueResult();
Do like this
Criteria criteria = session.createCriteria(User.class, "user")
.createAlias("user.address", "addr")
.add(Restrictions.eq("user.id", userId))
.setProjection(Projections.property("addr"));
Address address = (Address) criteria.list().get(0);
Couple of options:
use lazy="false" for Address object. If you have to use lazy=true for some reason, you can run this query in a separate session and override the lazy behavior in that session.
Use the database specific query to get a list of field names and then dynamically generate Projections by looping through the field names.
For example,
In mysql
SHOW COLUMNS FROM Address
In postgres
SELECT * FROM information_schema.columns
WHERE table_schema = your_schema
AND table_name = your_table
I hope this helps.

Categories

Resources