JPA SQL select and sum from entity manager - mysql

The following SQL script works in mysql:
select
LOGGING_ID,
SUM(NORMAL_HOURS +OVERTIME_HOURS +DOUBLE_TIME_HOURS) AS TOTAL_HOURS
FROM
LOGGING_DETAIL
GROUP BY 1
How would I do this with my entity manager?:
#PersistenceContext
private EntityManager database;
List<loggingDetail> loggingDetail = new ArrayList<loggingDetail>();
timeLoggingDetail = database.createQuery("").getResultList();
at the end I want the Logging_id and the total hours for that ID.
Thanks

The entity manager could called a named query that you set on your jpa entity object. I am assuming you have an entity object in this case. I suppose if you don't have that object you could do it in the query like you have it laid out in your question. I like having it in the entity object though so other calls can re-use it.
Entity object -
#Entity
#NamedQuery( name = "loggingDetail.getLoggingId", query = "select
LOGGING_ID,SUM(NORMAL_HOURS +OVERTIME_HOURS +DOUBLE_TIME_HOURS) AS TOTAL_HOURS
FROM LOGGING_DETAIL GROUP BY 1" )
public class LoggingDetail
{ ...}
The entity manager call will not get a fully populated loggingDetail object back since the query is not returning a full object, so you have to loop through an object array -
#PersistenceContext
private EntityManager database;
Query query = database.createNamedQuery( "loggingDetail.getLoggingId" );
List<Object[]> obj = query.getResultList();
for( Object[] objects : obj )
{
String logId = (String) objects[0] ;
String logTime = (String) objects[1] ;
}

Related

#SqlResultSetMapping is not working with date field

I have following very straightforward code.
#SqlResultSetMapping(name="getTestTable", classes = {
#ConstructorResult(targetClass = someEntity.class,
columns = {
#ColumnResult(name="some_date", type=Date.class)
})
})
Query:
getEntityManager().createNativeQuery("SELECT distinct some_date from test " );
List<someList > list=query. getResultList();
Entity:
someEntity
#Column(name = "some_date")
#JsonFormat(pattern="dd/MM/yyyy")
private Date someDate;
public someEntity(java.util.Date someDate) {
super();
this.someDate= someDate;
}
There is data in 'someDate' column and query is working fine on Sql-Editor, but when running above code "some_date" is always null.
What is wrong in this code? How should I get value for date?
I even converted the date format and declared field String in code but nothing worked.
1) As you are using java.util.Date you should mark your date field with temporal type:
#Column(name = "some_date")
#Temporal(TemporalType.DATE)
#JsonFormat(pattern="dd/MM/yyyy")
private Date someDate;
2) Define your native query as NamedNativeQuery:
#NamedNativeQuery(name = "testTableNativeQuery",
query = "SELECT distinct some_date from test",
resultSetMapping = "getTestTable")
3) Update your query execution:
getEntityManager().createNamedQuery("testTableNativeQuery", someEntity.class).getResultList();

Spring data JPA , result object has numbers instead of column names

i would like some help trying to do the following.I want to get the number of purchases of each user in the database grouped by his name and id.But it's very hard to do compared to simple sql.
I have the following code in my PurchaseRepository that extends CrudRepository
#Query("SELECT p.user.name as Name,p.user.id as Id,Count(p) as Purchases from Transaction p GROUP BY p.user.id")
List<Object> purchaseNumOfEachUser();
First of all im not sure if this is the right query because i wanted to do Count(*) but says its not valid.
Secondly , the object i get returned when converted to Json via a controller is like
0:{
0:"John",
1:2, //id
2:5 //purchases
}
What i would like to get is
0:{
"Name" : "John",
"Id" : 1 ,
"Purchases" : 2
},
1:{
....
}
Any ideas?
1) The query:
SELECT p.user.name as Name, p.user.id as Id, Count(p) as Purchases
from Transaction p GROUP BY p.user.id
should be
SELECT p.user.name as Name, p.user.id as Id, Count(p) as Purchases
from Transaction p GROUP BY p.user.name, p.user.id
You must group by all rows you are selecting.
2) the result
The result of the query is List if you want to have something meaningful you should consider the constructor expression that let's you create your own objects.
For example
package mypackage;
public class PurchaseInfo {
private final String name;
private final Integer id;
private final Long count;
public PurchaseInfo(String name, Integer id, Long count) {
this.name = name;
this.id = id;
this.cound = count;
}
// getters
}
This class can then be use in the query (please notice the fully qualified class name after NEW):
SELECT NEW mypackage.PurchaseInfo(p.user.name, p.user.id, Count(p))
from Transaction p GROUP BY p.user.name, p.user.id
The result will then be List and you will get it nicely serialized to JSON.
Read more about the Constructor Expression here:
https://vladmihalcea.com/the-best-way-to-map-a-projection-query-to-a-dto-with-jpa-and-hibernate/

How to use FIELD() function of mysql in JPA

My sql query is something like
Select * from tableA order by FIELD('ID', 3, 5, 2)
How do I implement this in JPA using criteria builder?
EDIT
List<Integer> ordList = new ArrayList<Integer>();
ordList.add(3);
ordList.add(5);
ordList.add(2);
public List<Order> getOrderBys(CriteriaBuilder cb, Root<?> root) { 
List<Order> orders = new ArrayList<Order>();         
orders.add(cb.function("FIELD", Integer.class, root.get("id"), ordList));
     return orders; 
}
Above is my function which gives list of oders, I want to add only one order same as above sql query. How can I add/call that function in orders.add() method? The above method gives error.
We can use with the native query flag.
For example.,
#Query(value="select * from table_name where id IN :id ORDER BY FIELD(id,:id)",nativeQuery = true)
List<Entity Name> getByIds(#Param("id") List<Integer> id);
For that simple case I would not use the FIELD function but would sort the result by the sorted list, as described here.
E.g.:
List<Integer> ordList = new ArrayList<Integer>();
ordList.add(3);
ordList.add(5);
ordList.add(2);
List<Entity> resultList = query.getResultStream()
.sort(Comparator.comparing(entity -> ordList.indexOf(entity.getId())))
.collect(Collectors.toList();

Cannot Seem to retrieve data from table in the order of the database table's column order

I want to to retrieve data from table in the order of the database table's column order.
Suppose my sql query is
String sql_string = "select * "
+ "from CUSTOMER_INFO "
+ "order by customer_last_name, customer_first_name";
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
List<Map<String,Object>> results = session.createSQLQuery(sql_string)
.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE)
.list();
In database, the table's column order is like A,B,C,D.
But when I retrieve the data and iterate through it, the entrySet is like C,A,D,B. (int,float,float,String)
I think the data is being retrieved based on its datatype.
I need the retrieved entrySet in the same order as it exists in database's table.
I also tried specifying the column names in select query which was of no use.
CUSTOMER_INFO is model class mapped to sqllite through hibernate.
#Entity
#Table(name = "CUSTOMER_INFO")
public class CustomerInfo{
#Column
private int C;
#Column
private float A;
#Column
private String B;
#Column
private float D;
//getters and setters
}
Using Sqllite 3.6, hibernate, JSP.
Any help is appreciated.

hibernate optional relationship not showing data

I am using hibernate with MySQL Db. I have a table of business with some fields and relations. in relations, one relation is optional.
#ManyToOne(fetch = FetchType.LAZY)
#NotFound(action=NotFoundAction.IGNORE)
#JoinColumn(name = "modified_by", nullable = true)
public Users getModifiedBy() {
return this.modifiedBy;
}
public void setModifiedBy(Users modifiedBy) {
this.modifiedBy = modifiedBy;
}
now when I fetch data using the following hql it work fine
String hql = "from Business";
Query query = session.createQuery(hql);
list = query.list();
if i changed hql to the following then it shows 0 result.
String hql = "select new com.ba.Business(business.businessId,business.slUsersByCreatedBy.userId,business.modifiedBy.userId,business.bizType.bizTypeId) from com.ba.Business business order by business.businessName";
How to manage this as modifiedBy is null. There were different solution available which i tried like setting optional to true and setting #NotFound but nothing worked.
SQL Created by hql is following.
select business0_.business_id as col_0_0_, business0_.createdBy as col_1_0_, business0_.modified_by as col_5_0_, business0_.biz_type_id as col_9_0_ from _business business0_, _users users1_, _users users4_, _biz_type biztype7_ where business0_.createdBy= users1_.web_user_id and business0_.modified_by= users4_.web_user_id and business0_.biz_type_id= biztype7_.biz_type_id order by business0_.business_name
it is using "and" for joins. If i explicitly add joins by adding following with hql then the result remain same.
left join business.modifiedBy modifiedBy
Is there any solution available?
When you use business.modifiedBy in the query, it implicitly converts to inner join, and that's why you don't get any results. Change it to this and it should work
String hql = "select new com.ba.Business(business.businessId, business.slUsersByCreatedBy.userId, mb.userId, business.bizType.bizTypeId) from com.ba.Business business left join business.modifiedBy mb order by business.businessName";