Unexpected token error at table alias using hibernate - java

I am using Spring hibernate.
My code is as below:
String hql = "select a.candidate_id_fk, count(*) from Answers a , Question b where a.question_id_fk = b.id"+""
+"and a.answer=b.correct_answer group by a.candidate_id_fk";
Session session = sessionFactory.getCurrentSession();
List list = session.createQuery(hql).list();
Error:
org.hibernate.hql.internal.ast.ErrorCounter reportError
unexpected token: a

Related

Hibernate runtime exception SQLGrammarException

Hibernate gives me a run time error to the following query.It's saying that there is a syntax error.
ERROR: Syntax error: Encountered "," at line 1, column 16.
Note that transaction handling handled at the service layer that's why session related lines are not in the code.
String hql = "UPDATE Lecturer L set L.id=:id,L.name=:name,L.department=:department,L.center=:center,L.facultyType=:facultyType,L.rank=:rank,L.level=:level,L.building.id=:buildingId,L.building.building=:building where L.id=:prevId";
Query query = session.createQuery(hql);
query.setParameter("id", lecturerDTO.getId());
query.setParameter("name", lecturerDTO.getName());
query.setParameter("department", lecturerDTO.getDepartment());
query.setParameter("center", lecturerDTO.getCenter());
query.setParameter("facultyType", lecturerDTO.getFacultyType());
query.setParameter("rank", lecturerDTO.getRank());
query.setParameter("level", lecturerDTO.getLevel());
query.setParameter("buildingId", lecturerDTO.getBuildingDTO().getId());
query.setParameter("building", lecturerDTO.getBuildingDTO().getBuilding());
query.setParameter("prevId", prevId);
query.executeUpdate();

how to fetch last column of the selected table using hibernate?

i am trying to fetch the id of last column in descending order.
the query which returns last column is
select id from(select id from challan
order by id desc) where ROWNUM=1;
now i am trying to do same thing using hibernate.
public long getIdOnChallanTable() {
session = sessionFactory.openSession();
trans = session.beginTransaction();
Query<Object[]> query = session.createNativeQuery("select id
from(select id from challan order by id desc) where ROWNUM=1;");
Long value = 0L;
List<Object[]> list = query.getResultList();
for ( Object lst : list){
Object[] objects =(Object[]) lst;
value=(Long)(objects[0]);
}
return value;
}
and the error is:
2017-07-26 12:37:36 [http-nio-7080-exec-1] WARN :: SQL Error: 911, SQLState: 22019
2017-07-26 12:37:36 [http-nio-7080-exec-1] ERROR:: ORA-00911: invalid character
update error javax.persistence.PersistenceException:
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
You don't need the semicolon at the end of the query and please use proper whitespacing. In the FROM clause, you don't have the whitespace between the subquery and the FROM keyword.
Note: don't forget to commit/rollback the transaction at the end and handle the exceptions as well. I hope this was just a sketch to show us the problem and not a code from a real world application.

Trouble when using clase WHERE ... IN (list)

I'm having trouble when trying to retrieve from database using Hibernate. What I'm trying to do is to retrieve questions from the database (using Hibernate with HSQLDB) where the Tag tag is contained in the question list. Here is the error:
06-Jan-2017 19:43:26.021 WARN [http-apr-8080-exec-4] org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions SQL Error: -5585, SQLState: 42585 06-Jan-2017 19:43:26.021 ERROR [http-apr-8080-exec-4] org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions malformed numeric constant: .
Here the query:
Query query = session.createQuery("FROM Question q WHERE (:someTag) in (q.tagList) ORDER BY (q.creationDate) DESC").setParameter("someTag", tag).setMaxResults(amount);
And here the complete method:
public static List<Question> list(Tag tag, int amount){
Session session = HibernateUtil.getSession();
Query query = session.createQuery("FROM Question q WHERE (:someTag) in (q.tagList) ORDER BY (q.creationDate) DESC").setParameter("someTag", tag).setMaxResults(amount);
return query.list();
}
You need to use elements clause if you are trying to check whether a list contains an element, in this case, the query would look like this:
"FROM Question q WHERE :someTag in elements(q.tagList) ORDER BY (q.creationDate) DESC"

Hibernate having difficulty with '#' character in HQL

Working with hibernate and spring social,
I am trying to query the database by email address.
when i do this query:
public Account findAccountByUsername(String username) {
Session session = sessionFactory.getCurrentSession();
String selectQuery = "FROM Account as account WHERE account.username = "+username;
Query query = session.createQuery(selectQuery);
#SuppressWarnings("unchecked")
List<Account> results = query.list();
if (!results.iterator().hasNext())
return null;
return results.iterator().next(); }
i get this exception
2013-01-22 14:37:13,090 [DEBUG] [HibernateTransactionManager,doBegin(),569] - Exposing Hibernate transaction as JDBC transaction [com.mchange.v2.c3p0.impl.NewProxyConnection#3b249bb2]
2013-01-22 14:37:13,352 [DEBUG] [QueryTranslatorImpl,parse(),272] - parse() - HQL: FROM masterPackage.model.orm.Account as account WHERE account.username = myEmail#gmail.com
2013-01-22 14:37:13,383 [DEBUG] [AbstractPlatformTransactionManager,processRollback(),843] - Initiating transaction rollback
2013-01-22 14:37:13,384 [DEBUG] [HibernateTransactionManager,doRollback(),672] - Rolling back Hibernate transaction on Session [org.hibernate.impl.SessionImpl#294a7134]
2013-01-22 14:37:13,385 [DEBUG] [JDBCTransaction,rollback(),186] - rollback
.......
2013-01-22 14:37:18,818 [WARN] [ProviderSignInController,oauth2Callback(),177] - Exception while handling OAuth2 callback (unexpected char: '#' [FROM masterpackage.model.orm.Account as account WHERE account.username = myEmail#gmail.com]). Redirecting to /signin
is there a way to work around this problem?
There is always a way to save the # character in the email address as some other character, but i am asking if there is something better then this solution.
Do not concatenate HQL query. Use named parameters instead. It is an implementation of Query Object Pattern in Hibernate.
For your case:
Session session = sessionFactory.getCurrentSession();
String selectQuery = "FROM Account as account WHERE account.username = :usernameParam";
Query query = session.createQuery(selectQuery);
query.setParameter("usernameParam", username);
#SuppressWarnings("unchecked")
List<Account> results = query.list();
if(results.isEmpty()){
return null;
} else {
return result;
}
Offtop: recommended never return null value for such method. Better is to return an empty collection. For example return new ArrayList<>(); Thus you able to use Null Object pattern implicitly.

subquery and aliases with criteria api

My question is rather simple: I have this query:
SELECT * FROM TABLE t WHERE
(SELECT count(*) FROM TABLE tbis WHERE TRUNC(t.date) = TRUNC(tbis.date))>1 ;
the field date is a timestamp.
How do I do that with the criteria API?
I have something like this (trunc() is valid with my db server, the sql request works.):
Criteria crit = session.createCriteria(Myclass.class, "t");
crit.createAlias("t.date", "dateT");
DetachedCriteria subcrit = DetachedCriteria.forclass(MyClass.class, "tbis");
subcrit.createAlias("tbis.date", "dateTbis");
subcrit.add(Restrictions.sqlRestriction("TRUNC(dateT) = TRUNC(dateTbis)"));
subcrit.setProjection(Projections.count("id"));
crit .add(Subqueries.gt(1, subcrit));
return crit.list();
Somehow in the log, i got:
org.hibernate.QueryException: not an association: date
I tried various things, but couldn't get it to work...
I tried:
Criteria crit = session.createCriteria(Myclass.class, "t");
DetachedCriteria subcrit = DetachedCriteria.forclass(MyClass.class, "tbis");
subcrit.add(Restrictions.sqlRestriction("TRUNC(t.date) = TRUNC(tbis.date)"));
subcrit.setProjection(Projections.count("id"));
crit .add(Subqueries.gt(1, subcrit));
return crit.list();
and the SQL condition generated was:
TRUNC(t.date) = TRUNC(tbis.date))
with the log:
18:34:04,461 WARN [JDBCExceptionReporter] SQL Error: 904, SQLState: 42000
18:34:04,461 ERROR [JDBCExceptionReporter] ORA-00904: "T"."DATE": invalid identifier
18:34:04,461 WARN [CriteriaAdapter] list exception:
org.hibernate.exception.SQLGrammarException: could not execute query
Also
Criteria crit = session.createCriteria(Myclass.class, "t");
DetachedCriteria subcrit = DetachedCriteria.forclass(MyClass.class, "tbis");
subcrit.add(Restrictions.sqlRestriction("TRUNC({t}.date) = TRUNC({tbis}.date)"));
subcrit.setProjection(Projections.count("id"));
crit .add(Subqueries.gt(1, subcrit));
return crit.list();
with the condition becoming:
TRUNC({t}.date) = TRUNC({tbis}.date))
and the logs:
18:36:28,206 WARN [TxConnectionManager] Connection error occured: org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener#1b3febd3[state=NORMAL mc=org.jboss.resource.adapter.jdbc.xa.XAManagedConnection#4cb16baf handles=1 lastUse=1343284588160 permit=true trackByTx=true mcp=org.jboss.resource.connectionmanager.JBossManagedConnectionPool$OnePool#7f16f514 context=org.jboss.resource.connectionmanager.InternalManagedConnectionPool#3c34353b xaResource=org.jboss.resource.adapter.jdbc.xa.XAManagedConnection#4cb16baf txSync=null]
java.lang.NullPointerException
at oracle.jdbc.driver.T4C8Oall.getNumRows(T4C8Oall.java:1153)
[...]
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
Or even:
Criteria crit = session.createCriteria(Myclass.class, "t");
DetachedCriteria subcrit = DetachedCriteria.forclass(MyClass.class, "tbis");
subcrit.add(Restrictions.sqlRestriction("TRUNC({t.date}) = TRUNC({tbis.date})"));
subcrit.setProjection(Projections.count("id"));
crit .add(Subqueries.gt(1, subcrit));
return crit.list();
With the same result as previously.
I think criteria is unable to detect the alias of the subquery... But I have to access that value, any workaround?
First you can try if you shouldn't put the { } only around the alias in the sqlRestriction :
subcrit.add(Restrictions.sqlRestriction("TRUNC({t}.date) = TRUNC({tbis}.date)"));
If you don't want to compare a part of the date fields (like the days), but want to see if the entire date fields are equal, you can just let Hibernate do the comparison like this:
Restrictions.eq(t.date, tbis.date)
If you want to compare a part of a date field, I refer you to this question.

Categories