java.lang.String cannot be cast HQL - java

Updated
Error says:
ava.lang.String cannot be cast to com.test.test.classes.TblTaxType
what is happening is when I add the tag select distinct taxtcode error is appearing. But when I removed the select tag like FROM tblTaxType tbl_tax_type WHERE bfnsCode = ? everything is fine. What is the cause? this is my code:
String hql = "SELECT DISTINCT TAXT_CODE FROM tbl_tax_type WHERE BFNS_CODE = ?";
try {
setSession(HibernateUtil.getSession());
#SuppressWarnings("unchecked")
List <TblTaxType> resultList = getSession().createSQLQuery(hql)
.setString(0, bfnsCode)
.list();

Your entity is probably named TblTaxType, not tblTaxType. Case matters.
Side note: don't name sql an HQL query. SQL and HQL are different languages.

Solved it using GROUP BY instead by using DISTINCT.
String hql = "FROM TblTaxType tbl_tax_type WHERE bfnsCode = ? GROUP BY taxtCode";

Your query returns TAXT_CODE, this field is a property of your TblTaxType entity, so you can't cast one property (string) in your main entity. This is the reason of your error.
If you need complete entity you must change your query but DISTINCT is not useful in this case because if you extract complete entity, there's ID field (different for each row). If you want a first element, you can add in your query ORDER BY clause with LIMIT 1 (is MySql).
A solution with GROUP BY works only if you use MySql as DBMS because if you have Sql Server the correct behaviour of field list / group by is: a field in field list must be in GROUP BY cluse or must be in aggregate function.

Related

Setting a collection parameter as a list for column values

I'm trying to write a query with a Collection parameter. It is assumed that query would turn this collection to a column of its values for the further operations. I'm using Spring, so now my query looks like:
#Query(value = "SELECT id FROM unnest(array[?1]) id", nativeQuery = true)
List<Object> getIds(Collection<String> ids);
It doesn't work, because Hibernate set collections as parameters in braces, so the real query will be send to DB:
SELECT id FROM unnest(array[('1', '2')]) id
This is not a valid query, the error is raising:
ERROR: a column definition list is required for functions returning
"record" SQL state: 42601
Right version of it must be:
SELECT id FROM unnest(array['1', '2']) id
So please can anybody tell me, if there is a way I could set a collection as query parameter without braces? Or maybe there is an another way to turn collection to column?

Hibernate exception on encountering mysql := operator

When I execute the following code the exception occurs:
Exception: org.springframework.orm.hibernate3.HibernateQueryException:
Not all named parameters have been set
Here is my code:
queryString = SET #quot=0,#latest=0,#comp='';
select B.* from (
select A.time,A.change,IF(#comp<>A.company,1,0) as LATEST,#comp:=A.company as company from (
select time,company,quote-#quot as `change`, #quot:=quote curr_quote
from stocks order by company,time) A
order by company,time desc) B where B.LATEST=1;
list = getHibernateTemplate().executeFind(new HibernateCallback(){
public Object doInHibernate(Session session)throws HibernateException,SQLException {
SQLQuery query = session.createSQLQuery(queryString);
query.setParameterList("list", custIds);
return query.list();
}
What is the reason for this behavior?
It's a little bit hard to understand, what is exactly the query you are executing, but if you need to use the colon character in native query, in your case as "assign a value" operator, you should escape all the colon occurances with \\ in your java String with the query, so it could be like:
select B.* from (
select A.time,A.change,IF(#comp<>A.company,1,0) as LATEST,#comp\\:=A.company as company from (
select time,company,quote-#quot as `change`, #quot\\:=quote curr_quote
from stocks order by company,time) A
order by company,time desc) B where B.LATEST=1;
Update: seems, it is not possible yet to escape the colons in Hibernate native queries, there is an open issue about it. That means, that you are not able to use a colons in Hibernate native queries not for the named parameters. You can try to create a function and call it instead of calling a query.
you can create a named query and then use it in spring jpa repository or hibernate. This link helped me from similar problem.

jpql left join fetch not returning results for like

In a spring mvc app using hibernate and MySQL, I have written the following query method to return a list of names with patients:
#SuppressWarnings("unchecked")
public Collection<Person> findPersonByLastName(String ln) throws DataAccessException{
Query query = this.em.createQuery("SELECT DISTINCT pers FROM rimPerson pers left join fetch pers.names nm WHERE nm.family LIKE :lnm");
query.setParameter("lnm", ln);
return query.getResultList();
}
This is producing the following hibernate sql:
Hibernate:
select distinct
person0_.hppid as hppid1_340_0_,
names1_.HJID as HJID1_89_1_,
person0_2_.classCode_HJID as classCod2_339_0_,
person0_1_.administrativeGenderCode_HJID as administ2_341_0_,
person0_1_.birthTime_HJID as birthTim3_341_0_,
names1_.DELIMITER_ as DELIMITE2_89_1_,
names1_.FAMILY as FAMILY3_89_1_,
names1_.named_entity_hppid as named5_89_1_,
names1_.SUFFIX as SUFFIX4_89_1_,
names1_.name_entity_HJID as name9_340_0__,
names1_.HJID as HJID1_89_0__
from
rim_person person0_ inner join rim_living_subject person0_1_ on person0_.hppid=person0_1_.hppid
inner join rim_entity person0_2_ on person0_.hppid=person0_2_.hppid
inner join rim_infrastructure_root person0_3_ on person0_.hppid=person0_3_.hppid
left outer join EN names1_ on person0_.hppid=names1_.name_entity_HJID
where names1_.FAMILY like ?
When I call the above jpql method with the following command, it returns zero results:
this.myappService.findPersonByLastName("");
I also get zero results when I cut and past the above generated hibernate code into the MySQL command line client and replace ? with ''.
If, however, I remove the where names1_.FAMILY like ? from the hibernate generated sql above and place the shortened sql into the MySQL command line client, I get four results, eachof which has a value for the lastname field.
How can I change the jpql so that it generates a hibernate query that returns the four results when `` is passed as the empty string parameter? I want the result set to include every result when the user gives empty input, but to give filtered results when the user types in any given text input.
The typical reason that like fails to do what you think it ought to do is to forget to put a wildcard in the pattern string. For example, if you want to match all user names that begin with 'Code' you must do something like name like 'Code%', NOT name like 'Code'. You can control exactly what your predicate matches with careful placement of %s in your string.
Try this to see all entities no matter what the value in family:
this.myappService.findPersonByLastName("%");
It is kinda cheesy to have the caller of findPersionByLastName have to put in the % wildcard. A better implementation is to have the caller specify which last name they are looking for, and then have the code that constructs the query put the wildcard in the right place. When you are looking for last names, you might do something like this:
query.setParameter("lnm", "%" + ln);
That would match anything that ends with the parameter that is passed to the method.

Hibernate returns list of nulls although executed SQL returns values

I'm using hibernate as an ORMapper. I want to execute an actually rather simple hql query:
SELECT a
FROM Foo a
WHERE a.status = :A0status
ORDER BY a.bookingTypeCode ASC,
a.priority ASC
This hql query is then converted into a sql query which looks something like this:
select a.*
from Foo a
where a.status='A'
order by a.bookingtypecode ASC,
a.priority ASC
When I execute the sql on the oracle database using the Oracle SQL Developer I get 17 rows returned. However, when I execute the hql query (using the list method of a Query I get a list of 17 elements that are all null. Although the number of elements is correct, not a single one of the elements is actually loaded.
This is the way I create and execute my query:
// the hql query is stored in the hqlQuery variable;
// the parameter are stored in a Map<String, Object> called params
Query hQuery = hibSession.createQuery(hqlQuery);
for (Entry<String, Object> param : params.entrySet()) {
String key = param.getKey();
Object value = param.getValue();
hQuery.setParameter(key, value);
}
List<?> result = hQuery.list();
Does anyone know what might be the problem here?
Update 1
I've recently upgrade from hibernate 3.2 to 4.3.5. Before the upgrade everything worked fine. After the upgrade I get this error.
I've set the Log level of hibernate to TRACE and found the problem. It was actually a mapping/logic/database error. The primary key consisted of two columns (according to the entity class) and one of these columns was nullable. However a primary key can never be nullable. Therefore hibernate always returned null.
If you have not set a custom (and buggy) ResultTransformer, my second best guess is that your debugger is lying to you. Does you code actually receives a list of null?
Also make sure to test with the code you are showing is. Too many times, people simplify things and the devil is in the details.
This error is happening to me. MySQL query browser works, but in hibernate of 7 columns and only one column always came with all null fields. I checked all the ids and they were not null. The error was in the construction of SQL Native. I had to change the way of writing it. Ai worked.
SELECT c.idContratoEmprestimo as idContratoEmprestimo,
c.dtOperacao as dataOperacao,
p.cpf as cpf,
p.nome as nome,
(Select count(p2.idParcelaEmprestimo) from EMP_PARCELA p2 where p2.valorPago > 0 and p2.dtPagamento is not null
and p2.idContratoEmprestimo = c.idContratoEmprestimo and p2.mesCompetencia <= '2014-08-01') as parcelasPagas, c.numeroParcelas as numeroParcelas,
pe.valorPago as valorParcela
FROM EMP_CONTRATO c inner join TB_PARTICIPANTE_DADOS_PLANO AS pp on pp.idParticipantePlano = c.idParticipantePlano
inner join TB_PARTICIPANTE as p on p.id = pp.idParticipante
inner join TB_PARTICIPANTE_INSTITUIDOR as pi on pi.PARTICIPANTE_ID = p.id
inner join EMP_PARCELA as pe on pe.idContratoEmprestimo = c.idContratoEmprestimo
where c.dtInicioContrato <= '2014-08-01' and pi.INSTITUIDOR_ID = 1
and c.avaliado is true
and pe.mesCompetencia = '2014-08-01'
and c.deferido is true
and c.dtQuitacao is null
and c.dtExclusao is null
and pe.valorPago is not null
group by c.idContratoEmprestimo
order by p.nome

Hibernate query.list getting cast exception

I am trying to connect to sql server 2012. by hibernate.
sql query: SELECT top 3 P.,v. FROM TBLPOMASTER P join tblVendorMaster v on v.vendorid=p.VendorId where v.VendorCode=10001 and p.ApprovedStatus='Y'
I tried to translate HQL query as
List<TblPomaster> poMasterList = new ArrayList<TblPomaster>();
String sqlQuery = "from TblVendorMaster as v, TblPomaster as p where v.vendorId=p.vendorId and v.vendorCode=:vendorLoginId and p.approvedStatus='Y'";
Query query = HibernateUtil.getSession().createQuery(sqlQuery)
.setParameter("vendorLoginId", vendorLoginId);
query.setMaxResults(3);
poMasterList=query.list();
return poMasterList;
in the above code query is executing fine. But query.list() throwing RuntimeException as java.lang.String cannot be cast to java.lang.Long
What is the solution for the above error
You can change your attribute's type from String to Long
You can cast the value to long:
Long.valueOf(String s).longValue();
It is also recommended to get the results of your query with:
query.getResultList();
Looks like you are retrieving a value from your database and hibernate is trying to convert that to a Long value.
Perhaps you have mapped this table column to an erroneously typed attribute in your model class. I'd check which text values are defined a 'numeric' within your class.
--
#theMarceloR: vendorCode datatype is Long in model file. But I am sending vendorLoginId a string value. is this the problem?
Change the attribute in the model config from Long to String and see what happens.
SOLUTION:
Sagar updated his code and now he's sending vendorCode as a parameter, the value is casted from string to long.

Categories