Get distinct values via hibernate - java

I want to get distinct values by a parameter:
#Transactional
public List<data> getAllFromColumn(String identifier) {
List<data> resultList = em.createQuery("SELECT DISTINCT p.market FROM data p", Data.class).getResultList();
return resultList;
}
My problem is that this only returns me a NullPointerException. Any recommendations what is wrong, or what I can do differently?
I appreciate your answer!

If HQL doesn't support select distinct (which it doesn't seem to according to the syntax), you can do this using group by:
SELECT p.market
FROM data p
GROUP BY p.market;

Related

JPA nativeQuery taking a list/set/array as parameter

Using a postgres database, I have the following entity : table cards.combo and column colors VARCHAR[], example of values {'red', 'blue'}
I want to find the Combos that have no colors in common, using the overlap operator (&&)
I can't find out how to formulate the correct nativeQuery, something similar to this :
#Query(nativeQuery = true, value = "SELECT * FROM cards.combo cc WHERE cc.colors && CAST(ARRAY[(:providedColors)] AS VARCHAR[])")
List<Combo> findOverlaps(#Param("providedColors") List<String> providedColors);
In a console, this test works fine :
SELECT * FROM cards.combo cc WHERE cc.colors && CAST(ARRAY['red'] AS VARCHAR[])
The syntax (:param) is supposedly correct with other primitive parameters (int, string). I struggle to get the param providedColors converted to an array[] in the query.
Thanks !
edit : found a workaround :provide colors as a csv string, and use && CAST(STRING_TO_ARRAY((:providedColors),',') AS VARCHAR[])
public interface EmployeeDAO extends JpaRepository<Employee,Integer> {
List<Employee> findByEmployeeNameIn(List<String> names);
// 1. Spring JPA In cause using method name
#Query("SELECT e FROM Employee e WHERE e.employeeName IN (:names)")
// 2. Spring JPA In cause using #Query
List<Employee> findByEmployeeNames(#Param("names")List<String> names);
#Query(nativeQuery =true,value = "SELECT * FROM Employee as e WHERE e.employeeName IN (:names)") // 3. Spring JPA In cause using native query
List<Employee> findByEmployeeName(#Param("names") List<String> names);
}

How to pass list in hql query where list is a value of a map

I have a leaveList containing 4 leave names.This leaveList is passed as map value.I want to get leave details from CompanyLeave Table by passing leaveList in hql query.Let be considered,my Company Leave Table contains 6 leave details.leaveList has 3 leave names.I want to get details of these 3 leaves from CompanyLeave Table.
Code for Hql query here leaveNameList is a list as well as map
public List<CompanyLeaveType> getByValidLeave(Map<String, Object> params) {
Query query = sessionfactory.getCurrentSession().createQuery("from CompanyLeaveType WHERE companyCode = :companyCode and leaveName IN (:leaveNames)");
query.setParameter("companyCode", params.get("companyCode"));
query.setParameter("leaveNames", params.get("leaveNameList"));
List<CompanyLeaveType> validLeaveDetails = query.list();
return validLeaveDetails;
}
N.B: I have got java.util.ArrayList cannot be cast to java.lang.String error.How can I pass list in hql query?
Use query.setParameterList(), Check the documentation here.
Query query = sessionfactory.getCurrentSession().createQuery("from CompanyLeaveType WHERE companyCode = :companyCode and leaveName IN (:leaveNames)");
query.setParameter("leaveNames", params.get("leaveNameList"));
Here you are trying to add a list object to the Hql query.
Here in this case the generated query by hibernate looks like this(actually its not happened and is just to make you to understand whats going on here)
1) Select *from companyLeveType_Table where companyCode=someX and leaveName in(ListObject)
But here the leaveName is of type java.lang.String and hence hibernte frameworks expects the values should be the string only. see the sample code (Hibernte expects this)
2) Select *from companyLeveType_Table where companyCode=someX and leaveName in("A","B","C");
from first query its obvious that hibernate framework tries to convert the java.util.ArrayList to java.lang.String and hence exception throws.
Solution 1)
public List<CompanyLeaveType> getByValidLeave(Map<String, Object> params) {
Query query = sessionfactory.getCurrentSession().createQuery("from CompanyLeaveType WHERE companyCode = :companyCode and leaveName IN (:leaveNames)");
query.setParameter("companyCode", params.get("companyCode"));
query.setParameterList("leaveNames", params.get("leaveNameList")); // changes here only remaining is same
List<CompanyLeaveType> validLeaveDetails = query.list();
return validLeaveDetails;
}
Solution 2:
Use Criteria api.
public List<CompanyLeaveType> getByValidLeave(Map<String, Object> params) {
Criteria criteria=session.createCriteria(CompanyLeaveType.class);
criteria.addCriteria(Restrictions.eq("companyCode",params.get("companyCode")))
.addCriteria(Restrictions.in("leaveName",params.get("leaveNameList")));
List<CompanyLeaveType> validLeaveDetails =criteria.list();
return validLeaveDetails;
}
I hope this helps you

How to send send an array of objects to a NamedQuery that needs the "id" of all the objects.

I am building a report from information received from a muti-select form element in a jsp page.
In my repository class I am getting an array of objects from that element. I need to call the getId function for each one of these objects and send those ids to the NamedQuery.
Here is a code example to help explain. I know how to handle a single object but with an array of objects I get lost at the .setParameter(1, employees[].getId()) part.
public List<RequestByRequester> getFormInformation(
Employee[] employees)
throws NoDataFoundException {
List<RequestByRequester> resultList = getEm().createNamedQuery(
"requestByRequestor.getRequestsByRequesters", RequestByRequester.class)
.setParameter(1, employees[].getId())
.getResultList();
return resultList;
}
By request the query:
SELECT EMP.EMPL_FIRST_NAME || ' ' || EMP.EMPL_LAST_NAME REQUESTER,
R.RQST_ID RQST_ID,
R.TITLE TITLE,
R.DESCRIPTION DESCR,
DECODE(R.RESOLUTION_DATE, NULL, 'Open', 'Closed') STAT
FROM TARTS.REQUESTS R, SYS_EMPLOYEES EMP
WHERE R.EMPL_ID_REQUESTED_BY = EMP.EMPL_ID
AND EMP.EMPL_ID IN (?)
ORDER BY 1, 5 DESC, 2
I tried calling Madame Mystique to get help with finding out what your query actually was, but no luck, so I'm just going to go for it...
Your named query should look something like this:
select x
from MyClass x
where x.children.id in (:ids)
then get your ids into a list
List<Integer> ids = new ArrayList<Integer>();
ids.add(someid); // etc
then use this to specify it in your query
.setParameter("ids", ids)

Select non-entities with JPA?

Is it possible with JPA to retrieve a instances of a non-entity classes with native queries?
I have a non-entity class that wraps two entities:
class Wrap{
Entity1 ent1;
Entity2 ent2
}
#Entity
class Entity1{
...
}
#Entity
class Entity2{
...
}
How can I do something like that?
Query q = entityManager.createNativeQuery("native select here");
List<Wrap> list = q.getResultList();
Is it possible with JPA to retrieve a instances of a non-entity classes with native queries?
No. Native queries can return entities only (if you tell them to do so by passing the resultClass or a resultSetMapping to the createNativeQuery method; if you don't, you will get collections of raw data).
In JPQL, you can use constructor expressions (SELECT NEW...) whith a non-entity constructor. But this is not supported for native queries, you'll have to do it manually.
JPA native query without entity - especially with complex queries (recursive, multiple joins, etc.) ?
This worked for me, but it's hibernate specific :
import org.hibernate.transform.Transformers;
Query query = entityManagerFactory.createEntityManager().createNativeQuery(SQL);
// Transform the results to MAP <Key, Value>
query.unwrap(org.hibernate.SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
query.setParameter("myNamedParam", myParam);
List<Map<String, Object>> list = query.getResultList();
for (Map<String, Object> map : list) {
System.out.println(map);
}
cf. https://www.programmerall.com/article/89371766511/
I think I found the solution.
There is a way to use the NEW keyword in constructing the query.
What I did to resovle this issue :
public List<ProductType> getProductByName(String productName) {
String sqlQuery = "select DISTINCT **NEW** project1.ProductType(o.name, o.revision) from Lhproduct o where o.name = :prodname";
Query qry = getEntityManager().**createQuery(sqlQuery);**
qry.setParameter("prodname",productName);
return qry.getResultList();
}
The ProductType is a non-entity object, a simple plain object implementing Serialiabale. But you need to define the appropriate constructor.
Happy coding :-)
Thanks and Regards,
Hari

Hibernate ordering

I have the Vehicles class and mapping file for it and i want to get all rows from vehicles table ordered by ID desc (I also need the same for my other tables).
I got the following code:
session = HibernateUtil.getSessionFactory().getCurrentSession();
tx = session.beginTransaction();
q = session.createQuery("from Vehicles order by ID DESC");
for (Iterator it=q.iterate(); it.hasNext();){
//some logic
}
But my set isn't ordered by ID and each time it has a different order like RAND() or something. I was wondering what is the easiest way to keep the functionality and just to add order by clause because I have the same syntax on many places...
Try after "q = session.createQuery(...);" part:
List results = q.list()
//loop through results
There is probably something wrong elsewhere, because "sort by id desc" part is correct. Check your database/mapping files if you have correct data types and if indexes are set properly.
I'm assuming your vehicles class looks like this? I'm using JPA here because thats what I know...
class Vehicles {
#Id
#Column(name="vehicles_id")
private int id;
// other stuff here
}
I don't expect your session.createQuery to be different from mine so wouldn't something like this work?
Query q = session.createQuery("select v from Vehicles v order by v.id desc");
Also you could use criteria if you wanted yeah?
class Main {
List<Vehicles> cars;
}
Criteria main = session.createCriteria(Main.class);
Criteria secondary = main.createCriteria("cars");
secondary.addOrder(Order.asc("id"));
Have you tried "from Vehicles v order by v.id desc"? Also another option is to add the comparable interface to the entity and then bring the list created by the query into a sortedset. That's typically what I do when I need to sort.

Categories

Resources