Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get column names from Hibernate query result in Java?

I'm writing a Java app that uses Hibernate to get data, in my app I have an input text area that takes an user typed-in sql command string and run that through Hibernate to get whatever data the user queries, so I don't know beforehand what the result table might look like and therefore don't know the column names, but I do need to display user query result in a table with column names relate to the data fields, how to achieve that in Hibernate ? I've tried the following code :

  Session session=HibernateUtil.getSession();
  session.beginTransaction();
  Query q=session.createQuery(hql);

  AliasToEntityMapResultTransformer INSTANCE=new AliasToEntityMapResultTransformer();
  q.setResultTransformer(INSTANCE);
  List<Map<String,Object>> aliasToValueMapList=q.list();

  for (Map<String,Object> map : aliasToValueMapList)
    for (Map.Entry<String,Object> entry : map.entrySet()) System.out.println(entry.getKey()+" - "+entry.getValue());

It gave me the following error message : Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sakila.entity.Actor cannot be cast to java.util.Map

It's pointing to the 1st for loop, since I'm new to Hibernate, don't know if it's doable in it, how to fix the above code ? Could someone show me some sample code that works in my case ?

Edit : As Marcel Stör mentioned below, I need to be able to allow both situations to happen and not limit users' ability to query any data, what's the best way to do it ?

like image 374
Frank Avatar asked Nov 04 '22 06:11

Frank


2 Answers

I don't quite understand but still dare to answer...

If you use HQL like this Query q=session.createQuery(hql); suggests you get back objects and not individual fields by default. This means you're out of luck anyway trying to map back the results to the query BUT you can simply use the object's field names as column names.

If what you get from the text area is plain SQL though, then you have to use session.createSQLQuery(sql). What you get back is a list of object arrays. However, here too you only get the data. You'd have to prohibit your users to use select * queries. Then you can use the name of the field/column in query as your output column names.

like image 96
Marcel Stör Avatar answered Nov 15 '22 09:11

Marcel Stör


I've got the same kind of problem for HQL query like

select new Map(id as id, name as name) from Person

that I use as view DTO

With one or more records I can iterate through the map that is element of List<Map<String, Object>. The problem only when I need to manage situation with empty dataset. For that case something like

public List<String> getAliases(String queryString) {
   ArrayList<String> list = 
       new ArrayList<String>(Arrays.asList(queryString.split("as ")));
   List<String> result = new ArrayList<String>();
   list.remove(0);
   for (String str : list) {
        StringTokenizer st = new StringTokenizer(str, ",) ");
        result.add(st.nextToken());
    }
    return result;
}
like image 30
bbones1967 Avatar answered Nov 15 '22 08:11

bbones1967