Issue in getting db data using Hibernate query - java

Please look below db table relationship
comapny to product->many to many
product to item->many to many
Now, I need to get All items used in a company by using hibernate. Below is my efforts.
Criteria c = sessionFactory.getCurrentSession().createCriteria(Company.class);
c.add(Restrictions.eq("companyId", companyId));
Criteria c2 = sessionFactory.getCurrentSession().createCriteria(Item.class);
c2.add(c);//not correct parameter and trying to correct
List<Item> data = c2.list();
Above code is not correct. Please help me by giving right direction!

Related

Springboot Data JPA : getRowCountByTableName(String tablename)?

I'm developing a Springboot Application. One of the features of this application is to show Database Information (like tablename, no.of records, etc) on the UI. Currently I'm stuck in writing the implementation for the method public int getRowCountByTableName(String tablename).
There are lot of tables in the database, based on the given name I have to return the rowcount of that table. I have done some research on this and found that Hibernate Criteria API can help.
String cName = map.get(tableName);//There is map which has <tableName,CanonicalNameOfTheEntity>
className = Class.forName(cName);
Criteria cr = dbSession.createCriteria(className);
cr.setProjection(Projections.rowCount());
rowCount = (Long) cr.uniqueResult();
But the problem is that Hibernate Criteria API is deprecated. So I'm not supposed to use this deprecated api as per my organization policy.
Can someone help me finding an alternative way to do this?
Thanks in advance!!

How to return hibernate collection entities without returning root entity

I would like to get elements of a collection (Set<SheetConfig>) for a set of objects (WorkbookConfig) from Hibernate without getting the primary objects(WorkbookConfig).
The underlying tables look like this:
workbook_config -> workbook_config_sheet_join <- sheet_config
If I just run it in my SQL utility, a successful SQL statement looks like this:
SELECT DISTINCT sheet_config_id FROM sheet_config AS sc
LEFT JOIN workbook_config_sheet_join AS wcsj
ON sc.sheet_config_id = wcsj.sheet_config_id
LEFT JOIN workbook_config AS wc
ON wc.workbook_config_id = wcsj.workbook_config_id
WHERE wc.group_id ="1"
ORDER BY sheet_name;
I would like to do this properly without using HQL.
My UNSUCCESSFUL attempt has resulted in this:
#SuppressWarnings("unchecked")
public List<SheetConfig> findAllForUser() {
List<SheetConfig> sheetConfigs = null;
Session session = getSession();
Criteria crit = session.createCriteria(WorkbookConfig.class)
.add(Restrictions.in(GROUP, getGroupsForUser()))
.setFetchMode(SHEET_CONFIGS, FetchMode.JOIN);
sheetConfigs = (List<SheetConfig>) crit.list();
return sheetConfigs;
}
This is still giving me WorkbookConfigs, but what I would like to do in a single pass is get SheetConfigs. I have spent the day on the Internet trying to find a coherent explanation of the Hibernate API, and I haven't been able to find what I would think is a solution to a fairly common requirement. I can always back out and just do most of the work in Java, but it seems like I should be able to do this with the Hibernate API. I appreciate any help, and also, if you can recommend a reference that explains not simply querying collections, but returning them, I would be grateful.
Did you look into the setProjection method on Criteria?
Using the setProjection method lets you select properties or objects from the executed query.
Hibernate Criteria documentation

How to use Hibernate to query a MySQL database with indexes

I have an application developed based on MySQL that is connected through Hibernate. I used DAO utility code to query the database. Now I need optimize my database query by indexes. My question is, how can I query data through Hibernate DAO utility code and make sure indexes are used in MySQL database when queries are executed. Any hints or pointers to existing examples are appreciated!
Update: Just want to make the question more understandable a little bit. Following is the code I used to query the MySQL database through Hibernated DAO utility codes. I'm not directly using HQL here. Any suggestions for a best solution? If needed, I will rewrite the database query code and use HQL directly instead.
public static List<Measurements> getMeasurementsList(String physicalId, String startdate, String enddate) {
List<Measurements> listOfMeasurements = new ArrayList<Measurements>();
Timestamp queryStartDate = toTimestamp(startdate);
Timestamp queryEndDate = toTimestamp(enddate);
MeasurementsDAO measurementsDAO = new MeasurementsDAO();
PhysicalLocationDAO physicalLocationDAO = new PhysicalLocationDAO();
short id = Short.parseShort(physicalId);
List physicalLocationList = physicalLocationDAO.findByProperty("physicalId", id);
Iterator ite = physicalLocationList.iterator();
while(ite.hasNext()) {
PhysicalLocation physicalLocation = (PhysicalLocation)ite.next();
List measurementsList = measurementsDAO.findByProperty("physicalLocation", physicalLocation);
Iterator jte = measurementsList.iterator();
while(jte.hasNext()){
Measurements measurements = (Measurements)jte.next();
if(measurements.getMeasTstime().after(queryStartDate)
&& measurements.getMeasTstime().before(queryEndDate)) {
listOfMeasurements.add(measurements);
}
}
}
return listOfMeasurements;
}
Just like with SQL, you don't need to do anything special. Just execute your queries as usual, and the database will use the indices you've created to optimize them, if possible.
For example, let's say you have a HQL query that searches all the products that have a given name:
select p from Product where p.name = :name
This query will be translated by Hibernate to SQL:
select p.id, p.name, p.price, p.code from product p where p.name = ?
If you don't have any index set on product.name, the database will have to scan the whole table of products to find those that have the given name.
If you have an index set on product.name, the database will determine that, given the query, it's useful to use this index, and will thus know which rows have the given name thanks to the index. It willl thus be able to only read a small subset of the rows to return the queries data.
This is all transparent to you. You just need to know which queries are slow and frequent enough to justify the creation of an index to speed them up.

avoiding multiple selects when using kew word "new" in hql

I have the following code in java.
List<UserHelper> users=List<UserHelper>)session.getNamedQuery("PkUser.loadHelperUsers").list();,
I think it does not matter what the "UserHelper" class is that's why I do not write it, not to overload my question. This is my namedQuery mentioned above.
#NamedQuery(name = "PkUser.loadHelperUsers", query = "SELECT new ge.tec.pto.ext.helpers.UserHelper(u) from PkUser u order by u.pkUserId desc"),
The problem is that the hql selects too many rows, I think the same number of rows that is in database in pk_user table.If anyone knows how to fix this please inform me. It will be very nice if the solution will not require to alter my "NamedQuery", It will be graet if I will have to change only my Query creation, But any solutions will be helpful, Thank you
Multiple selects when using Key word “`new`” in `hql`
There is no problem with your code and with NEW keyword .
Your query will return all the Rows in the UserHelper related Table
You should use a WHERE clause to get the required rows .
EX :
query = "SELECT new ge.tec.pto.ext.helpers.UserHelper(u) from PkUser u where username=:passedparamer order by u.pkUserId desc"

Need help creating JPA criteria query

I'm building my first Java EE web application using Glassfish and JSF. I'm fairly new to the criteria query and I have a query I need to perform but the javaee6 tutorial seems a little thin on examples. Anyway, I'm having a hard time creating the query.
Goal: I want to pull the company with the most documents stored.
Companies have a OneToMany relationship with Documents.
Documents has a ManyToOne relationship with several tables, the "usertype" column distinguishes them.
MySQL query:
SELECT USERID, COUNT(USERID) AS CNT
FROM DOCUMENTS
WHERE USERTYPE="COMPANY"
GROUP BY USERID
ORDER BY CNT DESC
Thanks
--update--
Based on user feedback, here is what I have so far:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Documents> cqry = cb.createQuery(Documents.class);
//Intersting Stuff
Root<Documents> root = cqry.from(Documents.class);
Expression userid = root.get("userID");
Expression usertype = root.get("userType");
Expression count = cb.count(userid);
cqry.multiselect(userid, count);
Predicate userType = cb.equal(usertype, "COMPANY");
cqry.where(userType);
cqry.groupBy(userid);
cqry.orderBy(cb.desc(count));
//more boilerplate
Query qry = em.createQuery(cqry);
List<Documents> results = qry.getResultList();
The error I get is:
Exception Description: Partial object queries are not allowed to maintain the cache or be edited. You must use dontMaintainCache().
Typical error, means nothing to me!
Your query doesn't return a complete entity object as you're only selecting two fields of the given table (this is why you're getting an error that says yadayadapartialyadayada).
Your solution is almost right, here's what you need to change to make it work—making it partial.
Instead of a plain CriteriaQuery<...> you have to create a tuple CriteriaQuery<..> by calling CriteriaBuilder.createTupleQuery(). (Basically, you can call CriteriaBuilder.createQuery(...) and pass Tuple.class to it as an argument. Tuple is a sort of wildcard entity class.)
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq= cb.createTupleQuery();
Root<Documents> root = cq.from(Documents.class);
Expression<Integer> userId = root.get("USERID");
Expression<String> userType = root.get("USERTYPE");
Expression<Long> count = cb.count(userId);
cq.multiselect(userId.alias("USERID"), count.alias("CNT"));
cq.where(cb.equal(userType, "COMPANY");
cq.groupBy(userId);
cq.orderBy(cb.desc(count));
TypedQuery<Tuple> tq = em.createQuery(cq);
for (Tuple t : tq.getResultsList()) {
System.out.println(t.get("USERID"));
System.out.println(t.get("CNT"));
}
(Accessing fields of a Tuple gave me an error if I didn't use aliases for them (in multiselect(...)). This is why I've used aliases, but this can be tackled more cleanly by using JPA 2's Metamodel API, which is described in the specification quite thoroughly. )
The documentation for CriteriaQuery.multiselect(...) describes the behaviour of queries using Tuple objects more deeply.
If you are using Hibernate, this should work:
ProjectionList pl = Projections.projectionList()
.add(Projections.groupProperty("userid"))
.add(Projections.property("userid"))
.add(Projections.count("userid"));
Criteria criteria = session.createCriteria(Document.class)
.add(Restrictions.eq("usertype",usertype))
.setProjection(pl)
.addOrder(Order.desc("cnt"));
Hope it helps!
Take a look into this easy tutorial. It uses JPA2 and Criteria
http://www.jumpingbean.co.za/blogs/jpa2-criteria-api
Regards!
You need to add a constructor to Documents with only userid and count because you will need it on:
cqry.multiselect(userid, count);

Categories