My query like this,
String sql="select p.productName,p.extendedFlag from product p where productId=? and productVersion=?";
SqlQuery sqlQuery=session.createSQLQuery(sql).addEntity(Product.class);
sqlQuery.setParameter(0,"newprofin2");
sqlQuery.setParameter(1,"newprofin2");
List product =sqlQuery.list();//error at this line
Product p=(Product)product.get(0);
please Help me,
and i am using Hibernate 3.
If you want to return the result as an entity you need to use "select * ..." (so hibernate can map all the column annotations) otherwise you have to stick with selecting only scalar values that are not mapped to the entity and need to be processed on a column basis.
Examples:
http://www.tutorialspoint.com/hibernate/hibernate_native_sql.htm
Related
I have a query like this:
Query 1:
select *
from items item
This is bind to an entity in SpringJPA.
Now I have to select one more column from another table like below.
Query 2:
select item.*,is.id
from items item
inner join item_state itm_s where item.id=itm_s.id
Now,there is a column "code" which exists in both item and item_state. I want to select it from item_state and not from item due to some data issues. I know the straight forward way is to write all columns in select statement,excluding code column from item and including code column from item_state.
But the thing is item table has around 100 columns.
Is there a good way to solve this issue without changing the entity class?
Look at Spring Data JPA projections and perform the following query:
#Query("select item.*, itm_s.code from items item join item.item_state itm_s where item.id = itm_s.id")
You will have to look at the resulting query to write your projection class.
We have a use case to count no. of rows returned by actual query. I am not getting how can I get it using criteria in hibernate.
For example suppose I want to run query
select sum(TOTAL_EARNINGS) from table where column1 = 'value1' group by column2);
Along with this query result I also want to get total rows return by above query(above query may have rownum limit also but for total rows I have to ignore rownum limit).
select count(*) from (select sum(TOTAL_EARNINGS) from table
where column1 = 'value1' group by column2);
Is there any easy way of getting this data. I am fine with running separate query to get count data but I am not getting how can I write this in hibernate using criteria. I can't even see any option in SubQueries which I can use
In general with criteria you can use projections.
You can do so, if you have an entity "Your" mapped by Hibernate:
Edited:
Accordingly to your comment, you need two results, a total count and a group by results.
//the group by results...
List result1 = session.createCriteria("Your.class").setProjection(Projections.projectionList()
.add(Projections.groupProperty("column2"))
.add(Projections.sum("totalErnings"))
).list();
//the total count result
return (Integer) session.createCriteria("Your.class").add(Restrictions.eq("column1", val)).setProjection(Projections.rowCount()).uniqueResult();
Updated
Error says:
ava.lang.String cannot be cast to com.test.test.classes.TblTaxType
what is happening is when I add the tag select distinct taxtcode error is appearing. But when I removed the select tag like FROM tblTaxType tbl_tax_type WHERE bfnsCode = ? everything is fine. What is the cause? this is my code:
String hql = "SELECT DISTINCT TAXT_CODE FROM tbl_tax_type WHERE BFNS_CODE = ?";
try {
setSession(HibernateUtil.getSession());
#SuppressWarnings("unchecked")
List <TblTaxType> resultList = getSession().createSQLQuery(hql)
.setString(0, bfnsCode)
.list();
Your entity is probably named TblTaxType, not tblTaxType. Case matters.
Side note: don't name sql an HQL query. SQL and HQL are different languages.
Solved it using GROUP BY instead by using DISTINCT.
String hql = "FROM TblTaxType tbl_tax_type WHERE bfnsCode = ? GROUP BY taxtCode";
Your query returns TAXT_CODE, this field is a property of your TblTaxType entity, so you can't cast one property (string) in your main entity. This is the reason of your error.
If you need complete entity you must change your query but DISTINCT is not useful in this case because if you extract complete entity, there's ID field (different for each row). If you want a first element, you can add in your query ORDER BY clause with LIMIT 1 (is MySql).
A solution with GROUP BY works only if you use MySql as DBMS because if you have Sql Server the correct behaviour of field list / group by is: a field in field list must be in GROUP BY cluse or must be in aggregate function.
Sample database table:
ID = 1, msgFrom = 'Hello', foobar = 'meh'
ID = 2, msgFrom = 'Goodbye', foobar = 'comments'
ID = 3, msgFrom = 'Hello', foobar = 'response'
Sample desired output (generated by hibernate query):
ID = 1, msgFrom = 'Hello', foobar = 'meh'
ID = 2, msgFrom = 'Goodbye', foobar = 'comments'
In the above example, the third record would be excluded from the results since the msgFrom column is the same. Let's say the Java/Hibernate class is called Message. I would like the results to be returned as a list of Message objects (or Objects that can be cast to Message, anyway). I want to use the Criteria API if possible. I saw this example on SO and it seems similar but I cannot implement it correctly as of yet.
select e from Message e
where e.msgFrom IN (select distinct m.msgFrom
from Message m
WHERE m.msgTo = ?
AND m.msgCheck = 0");
The reason I am doing this is to have the filtering of distinct records done on the database, so I am not interested in answers where I have to filter anything on the application server.
edit: Article showing basically what I want to do. http://oscarvalles.wordpress.com/2008/01/28/sql-distinct-on-one-column-only/
Please try this and let me know
DetachedCriteria msgFromCriteria = DetachedCriteria.forClass(Message.class);
ProjectionList properties = Projections.projectionList();
properties.add(Projections.groupProperty("messageFrom"));
properties.add(Projections.min("id"),"id");
msgFromCriteria.setProjection(properties);
Criteria criteria = s.createCriteria(Message.class);
criteria.add(Subqueries.propertiesIn(new String[]{"messageFrom","id"},
msgFromCriteria));
List<Message> list = criteria.list();
for(Message message:list){
System.out.println(message.getId()
+"-------"
+message.getMessageFrom()
+"-----"
+message.getFoobar());
}
The difficulty with this query is not so much with Hibernate, per se, but with the relational model in general. In the example, you say you expect rows 1 and 2, but why wouldn't you just as easily expect rows 2 and 3? It would be an arbitrary decision whether to return row 1 or row 3 since they both have the same value in the msgFrom field. Databases won't make arbitrary decisions like this. That's why distinct must be applied to the entire list of select columns, not a subset. There are database-specific ways of grabbing the first matching rows. For example, have a look at
SELECT DISTINCT on one column
Sometimes there will be a date column that you can use to decide which of the matching rows to return, but again the queries get somewhat complex:
How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?
Fetch the row which has the Max value for a column
If you don't care about any of the other columns, you can just use a simple distinct, combined with Hibernate's constructor syntax (not tested):
select new Message(msgFrom) from (select distinct msgFrom from Message)
but you have to accept throwing away all the other columns.
In the end, I often end up just doing this in code as a post query filter. Another option is to create a another table, say CurrentMessage, that includes msgFrom as part of the key. There will be more work in keeping this table up to date (you need to update a row everytime you add a row to the Message table) but querying will be much easier.
DetachedCriteria msgFromCriteria = DetachedCriteria.forClass(Message.class);
msgFromCriteria.setProjection(Projections.distinct(Projections.property("msgFrom")));
....
Criteria criteria = getSession().createCriteria(Message.class);
criteria.add(Subqueries.propertyIn("msgFrom", msgFromCriteria));
criteria.list();
I want to process the count column in my action how to do with help of hiberante.in my application every class is mapped to every table here I'm using billing table. In billing table details and other columns are there.
If i pass the query into execute sql query method it getting all the details, but it returns the count column as that corresponding dao class. How to process that column. Here is my query.
select u,b,b,count(b.details) from com.cod.model.Billing b,com.cod.model.User u where b.accountId=u.id and b.details not like '%Monthly Package With Usage Value Rs:0.0%' and b.details not like '%A/C Opened:%' and b.details not like '%Voucher Recharged%' and b.details not like '%default0%' group by u.username,b.details
Here it's getting user and billing table values but count column also comes as billing table object.
Don't make the results list type safe or hibernate will grab everything he can and push it in an instance of that object. When you make your results list not type safe hibernate will just return an List over which you can iterate and retrieve the fields you need.
List.get(0)[3] should result in you having your count.
String hql = "...";
Query query = session.createQuery(hql);
//List< com.cod.model.Billing> results = query.list();
List results = query.list();