How to select from multi tables (many to many)? - java

Database:
I want to get a list User, who have the same Monhoc (it has maMH= MH1).
My code :
private final SessionFactory sf = HibernateUtil.getSessionFactory();
Public List<User> listUserMonHoc() {
try {
sf.getCurrentSession().beginTransaction();
Query query = sf.getCurrentSession().createSQLQuery("select a.username, a.name from Monhoc b join b.User a where b.mamh = :id");
query.setString("id", "MH1");
List<User> list = query.list();
sf.getCurrentSession().getTransaction().commit();
return list;
} catch (Exception e) {
System.out.println("sai");
System.out.println(e.toString());
//return null;
e.printStackTrace();
return null;
}
}
ERROR message: ERROR: Table 'b.user' doesn't exist.
Thank you!

As i can see you have problems with your query. First you must join your third table and then search by id from the monhoc table.
Second there is a problem here
Query query = sf.getCurrentSession().createSQLQuery("select a.username, a.name from Monhoc b join b.User a where b.mamh = :id");
you must change b.User to User, cause b is allias of your Monhoc table.
So as a native query in MySql will look something like this :
SELECT u.username, u.name
FROM user AS u
INNER JOIN user_monhoc AS um
ON u.username = um.user_id
INNER JOIN monhoc AS m
ON um.mh_id = m.mamh
WHERE ....
I am using inner join (it can be different depents on your needs).

Related

Fetch relation of fetched relation in hibernate HQL query

I have entity Customer, Car:
#Entity
public class Customer{
List<Car> cars;
...
}
#Entity
public class Car{
List<Customer> previousOwners;
...
}
Basicly Customer can have multiple cars rented, and Cars remember previous owners.
Both entities have more relations, and i am omiting them.
Now want to retrieve all cars of Customer:
public List<Car> getCars(int customerId) {
List<Car> cars= new ArrayList<>();
Transaction tx = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
tx = session.beginTransaction();
cars= (List<Car>) session.createQuery("SELECT cars FROM Customer u JOIN u.cars cars WHERE u.id IN :ids ").setParameter("ids", customerId).list();
} catch (HibernateException e) {
if (tx != null) tx.rollback();
e.printStackTrace();
}
return cars;
}
This will return list of Cars, i need to use JOIN cuz lazyinitialization is set to FALSE.
Now i want to fetch Cars and their previos owners. But i am unable to think of any query, i tried using:
"SELECT cars FROM Customer u JOIN u.cars cars JOIN u.cars.previousOwners previousOwners WHERE u.id IN :ids " but this did nothing.
What i am aming for is to return object Car, with list inside, when i tried using
"SELECT cars, cars.previousOwner FROM Customer u JOIN u.cars cars JOIN u.cars.previousOwner previosOwner WHERE u.id IN :ids "
it returned the list of previousOwners, but not inside Car object, but as second element in returned list...
How can i create such query? Thanks fo help!
You probably want a (LEFT) JOIN FETCH query:
SELECT cars FROM Customer u
JOIN u.cars cars
JOIN FETCH cars.previousOwners
WHERE u.id IN :ids
This instructs Hibernate to join the cars.previousOwners relation even when it's declared to use lazy-fetching by default. Use a left join fetch if you also want to return cars with no previousOwners.
See the docs for more info.

Using a Query, Joining 4 tables in Hibernate Mapping

Currently i'm using PostgreSQL database in my Spring MVC web application. I'm able to get the values when i execute the query in PgAdmin tool.
In my query, I'm trying to join 4 tables and get the values.
My query is:
SELECT (s.school_id, u.first_name, u.last_name, u.username, u.email, p.plan_name, s.start_date, s.end_date, s.subscription_price, (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'T' and t.school_id = s.school_id), (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'A' and t.school_id = s.school_id), (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'S' and t.school_id = s.school_id)) FROM school s inner join user u on s.user_created = u.user_id inner join plan p on s.current_plan = p.plan_Id where s.application_id = 30 and s.site_id = 42;
When I use this same query in my Dao method, I'm getting error like:
No Dialect mapping for JDBC type: 1111
Code used in dao method:
public List<Object[]> getInformationValues(int applicationId, int siteId) throws HibernateException {
Session session = getCurrentSession();
Query query = session.createSQLQuery("SELECT (s.school_id, u.first_name, u.last_name, u.username, u.email, p.plan_name, s.start_date, s.end_date, s.subscription_price, (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'T' and t.school_id = s.school_id), (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'A' and t.school_id = s.school_id), (SELECT COUNT(*) FROM school_user t WHERE t.user_type = 'S' and t.school_id = s.school_id)) FROM school s inner join user u on (s.user_created = u.user_id) inner join plan p on (s.current_plan = p.plan_Id) where s.application_id = :applicationId and s.site_id = :siteId") .setParameter("applicationId", applicationId) .setParameter("siteId", siteId);
List<Object[]> results = query.list();
return results;
}
Is there any way to fix this issue?

Hibernate data fetching

Here is how I fetch data:
public static List<SubjectSubjectUsersUsers> getAllSubjectUsers()
{
List<SubjectSubjectUsersUsers> theList = null;
Session session = ServiceLocator.getSessionFactory().openSession();
try{
theList = session.createSQLQuery("SELECT s.name as subject_name, u.name as user_name, u.surname as user_surname, su.id as id from subjects s "
+ "join subject_users su on s.id = su.subject_id join users u on su.user_id = u.id")
.addScalar("subject_name", StandardBasicTypes.STRING)
.addScalar("user_name", StandardBasicTypes.STRING)
.addScalar("user_surname", StandardBasicTypes.STRING)
.addScalar("id", StandardBasicTypes.LONG)
.setResultTransformer(Transformers.aliasToBean(SubjectSubjectUsersUsers.class)).list();
}catch(Exception e){
e.printStackTrace();
}finally{
session.flush();
session.close();
}
return theList;
}
The problem is when I update data manually in the DB, the fetched data is not changed. But when I reload the server and IDE it works. What could be the cause of the problem? I guess I used the session object in the incorrect way. Thank you.
you need to set CacheMode to refresh
query.setCacheMode(CacheMode.REFRESH);
Your query will look like -
theList = session.createSQLQuery("SELECT s.name as subject_name, u.name as user_name, u.surname as user_surname, su.id as id from subjects s "
+ "join subject_users su on s.id = su.subject_id join users u on su.user_id = u.id")
.setCacheMode(CacheMode.REFRESH)
.addScalar("subject_name", StandardBasicTypes.STRING)
.addScalar("user_name", StandardBasicTypes.STRING)
.addScalar("user_surname", StandardBasicTypes.STRING)
.addScalar("id", StandardBasicTypes.LONG)
.setResultTransformer(Transformers.aliasToBean(SubjectSubjectUsersUsers.class)).list();
However it's a bad idea to update DB from outsite while using hibernate, otherwise you won't get benefits of hibernate cache.

Is there any spring jpa equivalent to following query

Query :
#Query("Select p.name,t.points from Player p,Tournament t where t.id=?1 And p.id=t.player_id")
I have my player and tournament entity and their corresponding JPA repositories. But the problem is we can get only entities from our query, but i want to do above query, please help me with this i am new to it.
this is my sql query i want to add but where to add i am not getting:
Select p.name, t.points_rewarded from player p, participant t where t.tournament_id="1" and t.player_id=p.id;
This is how you can do it with JPQL for JPA:
String queryString = "select p.name, t.points from Tournament t," +
" Player p where t.player_id=p.id " +
"and t.id= :id_tournament";
Query query = this.entityManager.createQuery(queryString);
query.setParameter("id_tournament", 1);
List results = query.getResultList();
You can take a look at this JPA Query Structure (JPQL / Criteria) for further information about JPQL queries.
And this is ho you can do it using HQL for Hibernate, these are two ways of doing it:
String hql = "SELECT p.name, t.points from Player p,Tournament t WHERE t.id= '1' And p.id=t.player_id";
Query query = session.createQuery(hql);
List results = query.list();
Or using query.setParameter() method like this:
String hql = "SELECT p.name, t.points from Player p,Tournament t WHERE t.id= :tournament_id And p.id=t.player_id";
Query query = session.createQuery(hql);
query.setParameter("tournament_id",1);
List results = query.list();
You can take a look at this HQL Tutorial for further information about HQL queries.
Note:
In both cases you will get a list of Object's array List<Object[]> where element one array[0] is the p.name and the second one is t.points.
TypedQuery instead of normal Query in JPA
this is what i was looking for, thanks chsdk for help, i have to create pojos class, and in above link answer is working fine foe me,
Here is my code sample
String querystring = "SELECT new example.restDTO.ResultDTO(p.name,t.pointsRewarded) FROM Player p, Participant t where t.tournamentId=?1 AND t.playerId = p.id ORDER by t.pointsRewarded DESC";
EntityManager em = this.emf.createEntityManager();
try {
Query queryresults = em.createQuery(querystring).setParameter(1, tournamentId);
List<ResultDTO> result =queryresults.getResultList();
return new ResponseEntity<>(result, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
} finally {
if (em != null) {
em.close();
}}

Inner join using native sql and hibernate

I am trying to inner join multiple and get as result an entity class Medecin so here is the methode :
public Medecin getMedecinByLoginPassword(String login, String password) {
String sql = "SELECT {m.*},{r.*},{s.*},{c.*} FROM medecin m INNER JOIN role r ON m.idrole = r.idrole INNER JOIN service s ON m.service_idservice = s.idservice INNER JOIN centre c ON s.centre_idcentre = c.idcentre WHERE m.login = :login AND m.password = :password";
SQLQuery query = getSessionFactory().getCurrentSession().createSQLQuery(sql);
query.addEntity("m",Medecin.class).addJoin("r", "m.role").addJoin("s", "m.service").addJoin("c", "s.centre").setResultTransformer(Transformers.aliasToBean(Medecin.class));
query.setParameter("login", login);
query.setParameter("password", password);
List results = query.list();
return (Medecin) results.get(0);
}
But i get this Error
GRAVE: org.hibernate.PropertyNotFoundException: Could not find setter for m on class com.mdsoft.gelt.model.Medecin
at org.hibernate.property.ChainedPropertyAccessor.getSetter(ChainedPropertyAccessor.java:44)
at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:57)
how can i get ride from this error

Categories