How to get the data in query(search result of hql)? - hql

I am a novice to use jdbc and I have some problems.
I use hql to search data in MySQL, and the result is Query type. I don't know how to get the data from the "Query".This is my code:
final String hql = "select app.appkey,app.type from " + getClassName() +
"app where app.appkey<>'no-appkey' group by app.type";
Query query = getEntityManager().createQuery(hql);
Thanks a lot.

You have to do the following:
final String hql = "select app.appkey,app.type from " + getClassName() + " app where app.appkey<>'no-appkey' group by app.type";
Query query = getEntityManager().createQuery(hql);
query.list(); //or query.getSingleResult();
query.list() will give a list of results.
query.getSingleResult() will give you a object.
You can check this.

If you are expecting a list of results, so:
List<Object[]> results = query.getResultList();
If you are expect one single result:
Object[] result = query.getSingleResult(); // if more than one result was found, this method will throw a NonUniqueResultException
If column information will be stored in a position of the Object array. Example:
String appKey = (String) result[0];
String appType = (String) result[1];
But work with Object array is not good. Try to use Dto, like explained here.

Related

HQL query returing null value on use of like operator for search

query = genericDAOImpl.getHibernateSession().createQuery("select t from ticket t where createdBy=:user and t.subject like concat("%", :summary, "%")
.setParameter("user", userId)
.setParameter("summary", inputBean.getSummary);
this is my query when I search for some values it returns the proper output but when I give null value for the search field it returns empty list actually it should return all the values when the search field is empty
You should just use a plain named placeholder for the predicate of the LIKE expression, and then bind the wildcard string from the Java side:
String sql = "select t from ticket t where createdBy = :user and t.subject like :summary";
query = genericDAOImpl.getHibernateSession().createQuery(sql);
query.setParameter("user", userId);
query.setParameter("summary", "%" + inputBean.getSummary + "%");

Spring Data - Custom DTO Query with filtering

I have a complexe application and I need to retrieve and filter 1000~5000 object for an xls export. Each object having multiple eager relationship (I need them for the export).
If I retrieve all the objects and their relationship as it is, I got some stackoverflow error.
Generaly when I need to make a big export, in order to make it efficient I use a DTO object with an #Query like this :
public interface myRepository extends JpaRepository<Car, Long> {
#Query("SELECT new com.blabla.myCustomObject(p.name, p.surname, c.model, c.number ...) "
+ "FROM Car c "
+ "LEFT JOIN c.person p "
+ "WHERE ... ")
List<myCustomObject> getExportCustomObject();
}
The problem is that the #Query is static and I want to add dynamic filter to my Query (Specifications, Criteria or some other system...)
How to do it ?
Specification cannot be used because this is only the where clause.
But you can use Criteria API. Here's an example. The BasicTeacherInfo is the DTO:
CriteriaQuery<BasicTeacherInfo> query = cb.createQuery(BasicTeacherInfo.class);
Root<Teacher> teacher = query.from(Teacher.class);
query.multiselect(teacher.get("firstName"),teacher.get("lastName"));
List<BasicTeacherInfo> results = em.createQuery(query).getResultList();
You can use #Param annotation to pass dynamic values to HQL, something like:
#Query("SELECT new com.blabla.myCustomObject(p.name, p.surname, c.model, c.number ...) "
+ "FROM Car c "
+ "LEFT JOIN c.person p "
+ "WHERE c.status = :status AND p.name = :name")
List<myCustomObject> getExportCustomObject(
#Param("status") Integer status,
#Param("name") String name
);
Below is one of the possible way where you can try to add offset and limit into your query you can make it dynamic with the help off placeholders.
Below is an sample pseudo code for reference:
Dao Layer:
#Query(value="SELECT e FROM tablename e WHERE condition_here ORDER BY e.id offset :offset limit:limit ")
public returnType yourMethod(String name, int offset, int limit);
Service Layer:
long count = number of records in db.
int a = // number of records to be fetched on each iterations
int num_iterations = count % a ;
int additionalrecords = count / a;
int start= 0;
while(num_iterations>0)
{
dao.yourMethod(start,a);
start = start+a;
count--;
// write your data to excel here
}
dao.yourMethod(start,additionalrecords);
Hope it is helpful.

generic hql select function given field and param

is this valid HQL?
If not (i assume not since im getting wrong result back). How/can i achieve this generic slect transaction?
String hql = "SELECT * from users Where :searchCriteria = :searchString";
List q = session.createSQLQuery(hql).addEntity(Users.class)
.setParameter("searchField", searchCriteria)
.setParameter("searchString", searchString).list();
Try this hql,
Criteria cr= session.createCriteria(Users.class);
cr.add(Restrictions.eq("searchField", searchCriteria);
cr.add(Restrictions.eq("searchString", searchString);
List<Users> user_data=(List<Users>)cr.list();

What is the correct way of reading single line of data by using Linq to SQL?

I'm very new to Linq, I can find multi-line data reading examples everywhere (by using foreach()), but what is the correct way of reading a single line of data? Like a classic Product Detail page.
Below is what I tried:
var q = from c in db.Products
where c.ProductId == ProductId
select new { c.ProductName, c.ProductDescription, c.ProductPrice, c.ProductDate };
string strProductName = q.First().ProductName.ToString();
string strProductDescription = q.First().ProductDescription.ToString();
string strProductPrice = q.First().ProductPrice.ToString();
string strProductDate = q.First().ProductDate.ToString();
The code looks good to me, but when I see the actual SQL expressions generated by using SQL Profiler, it makes me scared! The program executed four Sql expressions and they are exactly the same!
Because I'm reading four columns from a single line. I think I must did something wrong, so I was wondering what is the right way of doing this?
Thanks!
Using the First() extension method would throw the System.InvalidOperationException when no element in a sequence satisfies a specified condition.
If you use the FirstOrDefault() extension method, you can test against the returned object to see if it's null or not.
FirstOrDefault returns the first element of a sequence, or a default value if the sequence contains no elements; in this case the default value of a Product should be null. Attempting to access the properties on this null object will throw ArgumentNullException
var q = (from c in db.Products
where c.ProductId == ProductId
select new { c.ProductName, c.ProductDescription, c.ProductPrice, c.ProductDate }).FirstOrDefault();
if (q != null)
{
string strProductName = q.ProductName;
string strProductDescription = q.ProductDescription;
string strProductPrice = q.ProductPrice;
string strProductDate = q.ProductDate;
}
Also, you shouldn't have to cast each Property ToString() if you're object model is setup correctly. ProductName, ProductDescription, etc.. should already be a string.
The reason you're getting 4 separate sql queries, is because each time you call q.First().<PropertyHere> linq is generating a new Query.
var q = (from c in db.Products
where c.ProductId == ProductId
select new { c.ProductName, c.ProductDescription, c.ProductPrice, c.ProductDate }
).First ();
string strProductName = q.ProductName.ToString();
string strProductDescription = q.ProductDescription.ToString();
string strProductPrice = q.ProductPrice.ToString();
string strProductDate = q.ProductDate.ToString();

Get Row Count InvalidCast Exception from ScalarQuery

ScalarQuery<int> query = new ScalarQuery<int>(typeof(Role),
"select count(role.RoleId) from Role as role");
return query.Execute();
It fails with the invalidcast exception but succeeds when count is replaced with max.
Edit: Some databases will return long for count queries. For example SQL Server.
ScalarQuery<long> query = new ScalarQuery<long>(typeof(Role),
"select count(r) from Role r");
return query.Execute();
What database are you using? Could be that count does not return an int.
Your could also try using http://api.castleproject.org/html/T_Castle_ActiveRecord_Queries_CountQuery.htm
Not exactly the answer to the question, but a recommendation: if you want to avoid the hassle of having to issue a query at all yourself, then just use ActiveRecordMediator<T>.Count() (which has overloads that take criteria / filter strings if you want a conditional count) and all return int against all databases.
Based on testing the answers given to date, the following worked for me (including a where clause):
// Option 1
int result = ActiveRecordMediator<Post>.Count("BlogId = ?", blogId);
// Option 2
CountQuery query = new CountQuery(typeof(Post), "BlogId = ?", blogId);
int result = ActiveRecordMediator.ExecuteQuery(query);
// Option 3
ScalarQuery<long> query= new ScalarQuery<long>(typeof(Post),
"SELECT COUNT(*) FROM Post WHERE BlogId = ?", blogId);
long result = query.Execute();

Resources