2012-04-12 3 views
0

Это мое первое сообщение, поэтому, пожалуйста, несите меня. Я пытаюсь выполнить запрос HQL из метода, используя HibernateTemplate. Причина, по которой я делаю этот путь, состоит в том, что фактическая таблица имеет гораздо больше столбцов, но меня интересуют только две. Результат запроса используется при выполнении операции updateOrSave позже.Запросы HQL с использованием HibernateTemplate (Весна)

Так классовая структура выглядит следующим образом:

class XYZDAO { 
    ... 
    ... 

    public void createReview(....) { 
     ... 
     ... 
     class Temp { 
     private final float rating; 
     private final int count; 

     @SuppressWarnings("unused") 
     public Temp(float rating, int count) 
     { 
      this.rating = rating; 
      this.count = count; 
     } 
     public float getRating() 
     { 
      return rating; 
     } 
     public int getCount() 
     { 
      return count; 
     }   
     } 
     List<Temp> avgRatingWrapper = getHibernateTemplate().find("SELECT new Temp(AVG(RATING), COUNT(*)) FROM RATINGS WHERE ADVENTURE_ID = ?", Integer.parseInt(adventureId)); 
     ... 
     ... 
    } 
} 

Когда я запускаю код следующего исключения происходит:

Caused by: org.hibernate.hql.ast.QuerySyntaxException: RATINGS is not mapped [SELECT new Temp(AVG(RATING), COUNT(*)) FROM RATINGS WHERE ADVENTURE_ID = ?] 

У меня уже есть полномасштабное отображение отображения спящего режима для таблицы оценок:

<hibernate-mapping> 
    <class name="com.xyz.abc.dao.hibernate.Ratings" table="ADV_ADMN.RATINGS"> 
     <id name="id" type="int" column="ID"> 
      <generator class="seqhilo"> 
       <param name="sequence">ADV_ADMN.RATINGS_ID_SEQ</param> 
       <param name="allocationSize">1</param> 
      </generator> 
     </id> 
     <version name="timestamp" type="timestamp"> 
      <column name="TIMESTAMP" length="19" not-null="true" /> 
     </version> 
     <property name="adventureId" type="int"> 
      <column name="ADVENTURE_ID" not-null="true" /> 
     </property> 
     <property name="reviewer" type="string"> 
      <column name="REVIEWER" length="45" not-null="true" /> 
     </property> 
     <property name="rating" type="java.lang.Float"> 
      <column name="RATING" not-null="true" /> 
     </property> 
    </class> 
</hibernate-mapping> 

Теперь я понимаю, что мне нужно выполнить какое-либо сопоставление либо в hibernate.hbm.xml или предоставить аннотацию для класса Temp для отображения таблицы RATINGS. Мне было интересно, есть ли другой способ обойти проблему. Я решил, что если вы используете Session.createSqlQuery (....), то вы можете добавить к нему объекты, которые могут обойти проблему. Но я не уверен, что есть способ сделать это в HibernateTemplate.

Любая помощь/указатели с большой благодарностью.

ответ

1

код это не проверял, но я думаю, что вы имеете в виду что-то вроде этого. Создайте SQLQUery и определите скаляры как строки и используйте функцию getHibernateTemplate(). Execute().

return getHibernateTemplate().execute(new HibernateCallback<List>() { 

     public String doInHibernate(Session s) 
       throws HibernateException, SQLException { 
      SQLQuery sql=s.createSQLQuery("SELECT AVG(RATING) as r, COUNT(*) as c FROM RATINGS WHERE ADVENTURE_ID = ?"); 
       sql.setParameter(0, adventureId); 
      sql.addScalar("r"); 
      sql.addScalar("c"); 
      return sql.list(); 
     } 
    }); 

Если это HQL и getHibernateTemplate(). Найти то, что вы хотите использовать, а затем использовать «выберите ... из com.xyz.abc.dao.hibernate.Ratings»

+0

Хотя это решает проблему, я пытался избежать этого беспорядочного способа сделать это и хотел, чтобы это было просто, используя HQL. Я предполагаю, что другой из них будет состоять в том, чтобы создавать представления и сопоставлять класс с этим видом, который снова несколько более беспорядочен. – n00bc0der

0

HibernateTemplate.find() не принимает SQL-запрос, принимает HQL-запрос. Пока вы можете выразить свой запрос в HQL, было бы лучше сделать это.

В противном случае вам необходимо использовать Session.createSqlQuery() внутри обратного вызова, переданного в HibernateTemplate.executeFind().

Смотрите также:

+0

Спасибо за ответ. Я внесла изменения в свой первоначальный пост, где я достал Native SQL и изменил его на HQL. – n00bc0der

+0

Хотя я упоминал Native SQL в исходном вопросе, но я использовал HQL («SELECT new Temp (AVG (RATING)», COUNT (*)) FROM RATINGS WHERE ADVENTURE_ID =? »). Он также передает компиляцию парсером HQL. – n00bc0der

Смежные вопросы