Currently my code is
int customerId = 4;
String sql = "select id from coupon as A join coupon_use "
+ "as B on A.id=B.coupon where B.customer=" + customerId
+ " and B.like_at is not null;";
RawSql rawSql = RawSqlBuilder.parse(sql).create();
Query<Coupon> query = Ebean.find(Coupon.class);
query.setRawSql(rawSql);
List<Coupon> list = query.findList();
return ok(Json.toJson(list));
How do I avoid writing manual sql query but still have the ORM generate that query and return me the result?
Ebean will add appropriate joins based on the paths/properties used in the where and order by etc.
where couponUse.likeAt is not null.
Assuming couponUse.likeAt is the correct expression path ... Ebean will add a join to support the expression automatically.
Related
I'm using hibernate in my project and I'm trying to convert an existing sql query from DaoImplementation class to hql,
The sql query I have is
JdbcTemplate select = new JdbcTemplate(dataSource);
String sql = "SELECT * FROM (SELECT site_id,rtc,sigplan,cycle_time,health,phase_no,phase_time,active_groups,groupscolour,ip "+
"FROM status_data where rtc>='" + fromDate + "' and rtc<'" + toDate + "' and "+
"site_id=" + SiteId + " order by rtc desc limit "+recordLimit+" )as temp ORDER BY RTC ASC";
I wrote the hql version to get data from HealthLog table as
String hql = " select f from (select h from HealthLog h where rtc>='"+fromDate+"' and rtc <'"+toDate+"' "
+ "and siteId = "+siteId+" order by rtc desc limit "+limit+" ) as f order by rtc asc ";
return super.readListByHql(hql);
But the above hql throws the following exception
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 16 [ select f from (select h from com.traff.hibernate.model.HealthLog as h where rtc>='1974-08-01 14:10:00.0' and rtc <'1974-09-01 23:46:20.6' and siteId = 20 order by rtc desc limit 50000 ) as f order by rtc asc ]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47)
at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:79)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:276)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:180)
at org.hibernate.hql.intern
I also tried the below code snippet but that giving me wrong results
Criteria criteria = createEntityCriteria();
criteria.add(Restrictions.ge("rtc", fromDate));
criteria.add(Restrictions.lt("rtc", toDate));
criteria.add(Restrictions.eq("siteId", siteId));
criteria.setMaxResults(limit);
criteria.addOrder(Order.asc("rtc"));
criteria2 = criteria;
criteria2.addOrder(Order.desc("rtc"));
return criteria2.list();
Which is the correct way to achieve the result?
First of all, as already mentioned in the comments, you cannot do a subquery within the FROM clause in HQL.
See: Hibernate Documentation
Secondly, the limit keyword is not supported by HQL.
Usually you would use query.setFirstResult(0) and query.setMaxResults(recordLimit) methods where query has the type of the Query Interface. But since you are using the limit in a subquery, there is no way.
See: How to set a limit to inner query in Hibernate?
Some options:
Use a native SQLQuery
Since you are only sorting in the outer Query. You could only execute the inner query and sort in Java.
Example for Option 2:
Session session = factory.openSession();
Query query = session
.createQuery("FROM HealthLog "
+ "WHERE rtc >= :rtcL and rtc < :rtcG and siteId = :siteId "
+ "ORDER BY rtc DESC");
query.setParameter("rtcL", fromDate);
query.setParameter("rtcG", toDate);
query.setParameter("siteId", siteId);
query.setFirstResult(0);
query.setMaxResults(recordLimit);
List<HealthLog> res = query.list();
session.close();
Collections.sort(res, new Comparator<HealthLog>() {
public int compare(HealthLog o1, HealthLog o2) {
return o1.getRtc().compareTo(o2.getRtc());
}
});
The query above returns HealthLogs with all attributes. If you want to only retrieve specific attributes, you can add a SELECT new HealthLog(siteId,rtc,sigplan,cycle_time,...) to your Query with a fitting constructor in HealthLog.
Please note that the code snippet might not be ready to use, since i do not know your model and attribute names.
How do I accomplish this custom sort by field feature available in MySQL in hibernate?
select * from pet order by field(species, 'cat', 'dog', 'bird');
For some business reason, I need to enforce a custom ordering.
PS -I am new to hibernate.
I ended up writing an HQL like this
commaDelimitedSpecies = "'cat', 'dog', 'bird'";
orderBySpecies = " ORDER BY FIELD(species, " + commaDelimitedSpecies + ") DESC";
Query q = getSession().createQuery("FROM PetModel pet" + orderBySpecies);
With Spring HibernateDAO:
getHibernateTemplate().findByNamedParametersQuery(
"FROM MyEntity me WHERE me.id IN :ids ORDER BY FIELD(id, :ids)", new String[] {"ids"}, new Object[] {uuidList.toArray()},uuidList.size()
);
Note: getHibernateTemplate returns an instance of org.springframework.orm.hibernate3.HibernateTemplate
I'm trying to execute a Criteria query but when I execute the code, the SQL only brings up company_synonym in the from clause, not the other two.
The mappings are:
Company has 1-to-Many CompanySynonyms
Company has 1-to-Many CompanyProductRoles
I want the query to return CompanySynonym objects, so I tried this:
Criteria criteria = session.createCriteria(CompanySynonym.class, "cs")
.createAlias("cs." + CompanySynonym.COMPANY, "cmp")
.createAlias("cmp." + Company.COMPANY_PRODUCT_ROLE, "cpr")
.add(Restrictions.eq("cs." + CompanySynonym.TYPE, "1234"))
.add(Restrictions.eq("cpr." + CompanyProductRole.PRODUCT_ID, Integer.valueOf(productId)))
.add(Restrictions.isNotNull("cpr." + CompanySynonym.Company_ID))
.add(Restrictions.eq("cpr." + CompanyProductRole.ROLE_CODE, "AB"));
And it generates this SQL:
select this_.company_syn_id_i as company1_0_0_, this_.company_id_i as company5_0_0_, this_.cmp_syn_end_d as cmp2_0_0_, this_.cmp_syn_type_cd_c as cmp3_0_0_, this_.cmp_syn_c as cmp4_0_0_
from product.dbo.company_synonym this_
where this_.cmp_syn_type_cd_c=?
and cpr1_.product_id_i=?
and cpr1_.company_id_i is not null
and cpr1_.role_cd_c=c
What am I missing or doing wrong here?
I'm very, very new to Hibernate and JPA. I want to be able to apply ORDER BY and LIMIT clauses to a Hibernate(?) query, but am coming up empty. NOTE: I inherited this code.
Here is the current code:
public SomeCoolResponse getSomeCoolResponse(String myId) {
String queryString = "select aThing from AWholeBunchOfThings aThing " +
"join aThing.thisOtherThing oThing join oThing.StillAnotherThing saThing " +
"where saThing.subthing.id = :id";
Query q = getEntityManager().createQuery(queryString);
q.setParameter("id", myId);
List<MyThings> list = q.getResultList();
if(list.size() > 0) {
return list.get(0);
}
return null;
}
Instead of getting an entire list and then just returning the first result (which is the only one we need), I'd like to be able to apply a LIMIT 0,1 clause so that the query will be faster. Also, the query needs to be sorted descending on aThing.created which is a UNIX timestamp integer.
I've tried altering queryString like this:
String queryString = "select aThing from AWholeBunchOfThings aThing " +
"join aThing.thisOtherThing oThing join oThing.StillAnotherThing saThing " +
"where saThing.subthing.id = :id ORDER BY aThing.created LIMIT 0,1";
But Hibernate still returns the entire set.
I've looked at using the JPA CriteriaBuilder API, but it hurt my brain.
I'm a total n00b when it comes to this, and any help is greatly appreciated!
I think you need
q.setMaxResults(1);
See also the accepted answer here.
How do you do a limit query in HQL?
As to the "order by" clause you may include it in the queryString.
The JPQL equivalent to LIMIT start,max is:
setFirstResult and setMaxResults:
q.setFirstResult(start);
q.setMaxResults(limit);
Following SQL query:
select distinct hotel.country 'Country', hotel.id 'Hotel ID', hotel.Name'Name', room.id 'Room ID'
from room, stay, reservation, hotel
where
(stay.roomid = room.id)
and (stay.reservationid = reservation.id)
and (reservation.status != 'Booked' AND reservation.status != 'CheckedIn')
and (reservation.arrivaldate >= '2012-08-08')
and (reservation.leavedate <= '2012-08-15')
and (room.hotelid = hotel.id)
order by hotel.country, hotel.id, hotel.name, room.id asc
This will give me a list of available rooms per hotel per country. Now I have to put this in HQL, but I can't do so because of this:
Query query = session.createQuery("from room, stay, reservation, hotel where stay.roomid = room.id");
This doesn't work becuase stay.roomid is a Room object whereas room.id is just an integer. I'm pretty new to Hibernate/HQL and the reference manual didn't really bring me anywhere... How can I "convert" (scary word, I know this doesn't involve actual converting) this SLQ query to a HQL statement? Thanks.
UPDATE
Using a join result in the same problem
Query query = session.createQuery("" +
"from Stay stay " +
"join stay.ReservationID reservation " +
"join stay.RoomID room " +
"join room.HotelID hotel " +
"where (stay.RoomID = room.ID)");
I'm really missing something (probably very logical) here...
You haven't shown your entities, but, just as you would use joins in SQL, you need to use joins in HQL:
select ...
from Stay stay
join stay.reservation reservation
join stay.room room
join rom.hotel hotel
where (reservation.status != 'Booked' AND reservation.status != 'CheckedIn')
and (reservation.arrivaldate >= '2012-08-08')
and (reservation.leavedate <= '2012-08-15')
The Hibernate documentation has a whole chapter on HQL, and a section of this chapter about associations in HQL.