Hibernate detached criteria sum - java

This is my first post ever, I usually find the answers im looking for here, but this time i'm stumped.
Below are two sql queries - by first getting the values and then doing a "sum" on the results almost halves the duration, but replicating this with Hibernate Criteria is not that straight forward.
From related posts ive found it looks like the answer will more than likely be some DetachedCriteria function, but I cant find any examples where its been used with "sum".
SELECT (COUNT(DISTINCT(account))) FROM history;
duration 6363ms
SELECT COUNT(*) FROM (SELECT DISTINCT account);
duration 3624ms
My Hibernate criteria for the first query:
Session session = sessionFactory.openSession();
ProjectionList proj = Projections.projectionList()
.add(Projections.countDistinct("account"));
Criteria crit = session.createCriteria(History.class)
.setProjection(proj);
System.out.println(crit.list());

Related

Hibernate criteria joins multiple objects

i have a problem when retrieving count from criteria that impact my pagination.
i have this associations that work fine just the count of my result which is wrong for example i have 20 users in my DB but i got 60.
DetachedCriteria criteria = DetachedCriteria.forClass(User.class, "user");
criteria.createAlias("profile", "prof", Criteria.LEFT_JOIN);
criteria.createAlias("userAgencyRole", "adminAgency", Criteria.LEFT_JOIN);
criteria.createAlias("userAgencyRole.agency", "agency",Criteria.LEFT_JOIN);
criteria.createAlias("userAgencyRole.role", "role",Criteria.LEFT_JOIN);
result.setTotalRecords(userDalService.getCountFromCriteria(criteria));
For used projections i have :
ProjectionList projList = Projections.projectionList();
projList.add(Projections.property("name"), "name");
projList.add(Projections.property("email"), "email");
projList.add(Projections.property("userId"), "userId");
projList.add(Projections.property("profile"), "profile");
Any suggestions for this issue
You have to be careful while using Criteria API since joining a one-to-many relationship will not return distinct results by default.
This is a known problem and there are a few ways to prevent it. Some of them are discussed here.
Problem solved by invoking criteria alias if needed based on parameters received from my API. so the result wont be impacted by associations.

Subquery example in hibernate 5.2 Criteria API

I need to fire below query using hibernate 5.2+, but there is no such way given in hibernate official docs
SELECT * from candidate WHERE candidate.id NOT IN (SELECT candidate_id FROM interview)
N.B. I don't want to use named query or native query stuffs which
makes my code more database specific.
In the image below, Black circle is Candidate, White one is Interview.
Any idea how to run this.
Try something like this:
DetachedCriteria subquery = DetachedCriteria.forClass(Interview.class, "interview")
.setProjection(Projections.property("interview.candidate_id"));
DetachedCriteria criteria = DetachedCriteria.forClass(Candidate.class, "candidate")
.add(Subqueries.propertyNotIn("candidate.id", subquery));
Criteria executableCriteria = criteria.getExecutableCriteria(session);
List list = executableCriteria.list();
You could use an exists command.
from Candidate as candidate
where exists (
from Interview as interview where interview.candidate = candidate
)

sql query very slow in Hibernate, fast on mysql

I have a really simple query to select all rows from a table. In hibernate it always takes about 17-18 seconds. I specified, show_sql to be true. I copied the sql command directly to mysql and it took 0.00022 seconds...
this is the query:
SELECT
organizati0_.id AS id1_5_,
organizati0_.adminList AS adminLis2_5_,
organizati0_.demoAccount AS demoAcco3_5_,
organizati0_.disabled AS disabled4_5_,
organizati0_.enduserCredits AS enduserC5_5_,
organizati0_.name AS name6_5_,
organizati0_.pushNotificationRoom AS pushNoti7_5_,
organizati0_.totalLicenses AS totalLic8_5_,
organizati0_.usedLicenses AS usedLice9_5_
FROM
organization organizati0_
this is the code for the query:
Session session = ThreadSessionHolder.getThreadSession();
Query query = session.createQuery("from Organization ");
List list = query.list();
return list;
any ideas? this is driving me nuts
I found the issue.
I was performing an initialization operation in the constructor which shouldn't be done when selecting all

Hibernate Criteria for sum(distinct clicks)

I am unable to come up with the criteria which can perform sum(distinct clicks) in query. I am getting result with simple sql query but cannot make criteria to do the same.
Currently i can just do
.add(Projections.property("clicks").as("clicks"))
A simple sql query is like this
select sum(distinct clicks) as clicks, source as source, sum(jobs_sent) as jobsSent from tbl_click_count where date= '2016-09-04' and domain = 'somename' and whitelabel = 'somename' group by source, whitelabel, domain order by id desc
and my criteria is like
Criteria criteria = getSessionFactory().createCriteria(FeedClickCountModel.class)
.add(Restrictions.ge("date", startDate))
.add(Restrictions.le("date", uptoDate))
.setProjection(Projections.projectionList()
.add(Projections.sum("jobsSent").as("jobsSent"))
.add(Projections.groupProperty("source").as("source"))
.add(Projections.property("whiteLabel").as("whiteLabel"))
.add(Projections.property("domain").as("domain"))
.add(Projections.property("totalJobs").as("totalJobs"))
.add(Projections.property("clicks").as("clicks"))
// ^This i want is sum(distinct clicks)
.add(Projections.property("date").as("date"))
.add(Projections.property("id").as("id")))
.setResultTransformer(Transformers.aliasToBean(FeedClickCountModel.class));
Is there any way to do this without sqlprojection.
.add(Projections.distinct(Projections.property("clicks")));
Like this?
Projections.sum(Projections.countDistinct(propertyName));
Try this.
Without projections, you will need to use hibernate SQL or native SQL queries.

Hibernate Criteria filter Entity where ManyToMany relation contains multiple objects

I need help with Hibernate Criteria API.
I have a class Job that contain a list of Skill in ManyToMany relationship.
I need to select jobs based on a skill list given as parameter.
I've tried with Restriction.in("skill.id",ids) but this gives me wrong list.If i've selected 2 skills in search form i want the jobs that contain BOTH of them,so i need somehow to implement AND clause.
I've tried with Conjunction:
Conjunction and = Restrictions.conjunction();
for(Skill skill:job.getSkills()){
and.add(Restrictions.eq("skill.id",skill.getId()));
}
And this:
Criteria crit = criteria.createCriteria("skills",JoinType.LEFT_OUTER_JOIN);
for(Skill skill:job.getSkills()){
crit.add(Restrictions.eq("id", skill.getId()));
}
but it creates same alias for skill and it gives me no result.
sql is and (skill1_.ID=? and skill1_.ID=?)
Can anyone help me with this ?thanks
UPDATE:
HQL Query will be like:
select a from Job a where exists (select skill1.id from Skill skill1 join skill1.jobs r where r.id=a.id and skill1.id=1) and exists (select skill2.id from Skill skill2 join skill2.jobs r where r.id=a.id and skill2.id=4)
I need Criteria based on this.
for(Skill skill:job.getSkills()){
DetachedCriteria subquery = DetachedCriteria.forClass(Skill.class,"skill");
subquery.add(Restrictions.eq("id",skill.getId()));
subquery.setProjection(Projections.property("id"));
subquery.createAlias("jobs", "job");
subquery.add(Restrictions.eqProperty("job.id", "Job.id"));
criteria.add(Subqueries.exists(subquery));
}
I managed to solve it.now it works perfect.

Categories

Resources