Hibernate query.list getting cast exception - java

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.

Related

Error while getting sql record using EntityManager

I am using EntityManager in spring boot app to get result from this query
select (c.data::jsonb)->>'employee_Id' as empId from employee e where e.dept ='employee' and (e.data::jsonb)->>'section_id' = '1235'
Its giving me correct output in PgAdmin but in java code
List resultList = em.createNativeQuery(str).setParameter(1, sectionId ).getResultList();
Giving error ERROR: syntax error at or near ":" its breaking at data::jsonb .How do handle this using EntityManager.
You need to CAST like CAST(c.data as jsonb)->>'product_id' from string to JSONB. However i would highly suggest that you don't use TEXT for your JSON type data.
ALTER TABLE employee ALTER COLUMN data TYPE JSON USING data::JSON;
`

How to query a column with arraylist

I have a SQL database and one column of that database is a short array.
Column name
Data type
Order Id
Integer
Timestamp
Long
Activity
Short []
I want to query this table and get a count of rows that include a given short value in this Activity column. I have tried following SQL statement.
private static final String SYMPTOMS_GET_ACTIVITY_TYPE_COUNT =
"Select count(_val) from PatientTrigger where orderId = ? and ? = ANY(activity)";
But I am getting the following error: Unsupported expression: ANY(ACTIVITY) [type=Aggregate]
I am using Apache Ignite caches. Please tell me how to do this correctly.
The short version is that you can't. As noted in the comments, an array isn't a SQL type, at least not in ANSI SQL-99 which is what Ignite supports.
Typically you'd resolve this by normalising your cache and using a join in your SQL. That is, you'd have a one-to-many relationship between your PatientTrigger table and the (new) Activity table.

Spring Data JPA - problem with null parameter for NUMBER column type

I want to make dynamic query in which if particular parameter is sent, the Native query should filter the result based on it. In case it's null, it should not reflect the result.
I am using Spring Data JPA with Native query mechanism + Oracle DB
For String parameters this approach works fine
:email is null or s.email = :email
but for Integer parameters when they have value, the Query works but if the parameter is null the query fails with the error
Caused by: java.sql.SQLSyntaxErrorException: ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
I am using the exactly the same approach for for Integer instead of String
I am wondering whether the problem is on my side or it's some kind of bug?
In Oracle DB it's not worked this way. A workaround is using JPQL like
SELECT s FROM Entity s WHERE :id is null OR s.id = COALESCE(:id, -1)
Or for native query use TO_NUMBER function of oracle
SELECT s FROM Entity s WHERE :id is null OR s.id = TO_NUMBER(:id)

Is it mandatory to use addScalar() in createSqlQuery() in hibernate? Why do we need to specify the Data type to hibernate while executing SQL queries?

String sql = "select Band.band_id bandId from guest_band Band";
sessionFactory.getCurrentSession().createSQLQuery(sql)
.addScalar("bandId", Hibernate.LONG)
.list();
I got to know that addScalar() is used to state hibernate the DataType of the selected item, bandId in this case.
But my question is, why do we need to specify the type to hibernate? What does it internally perform? Secondly is it an exception if we don't addScalar()? Lastly, is there any alternate way how this can be achieved?
It's not mandatory but would certainly help to use
From https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querysql.html
The most basic SQL query is to get a list of scalars (values).
sess.createSQLQuery("SELECT * FROM CATS").list();
sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").list();
These will return a List of Object arrays (Object[]) with scalar values for each column in the CATS table. Hibernate will use ResultSetMetadata to deduce the actual order and types of the returned scalar values.
To avoid the overhead of using ResultSetMetadata, or simply to be more explicit in what is returned, one can use addScalar():
sess.createSQLQuery("SELECT * FROM CATS")
.addScalar("ID", Hibernate.LONG)
.addScalar("NAME", Hibernate.STRING)
.addScalar("BIRTHDATE", Hibernate.DATE)
This query specified:
the SQL query string
the columns and types to return
This will return Object arrays, but now it will not use ResultSetMetadata but will instead explicitly get the ID, NAME and BIRTHDATE column as respectively a Long, String and a Short from the underlying resultset.
This also means that only these three columns will be returned, even
though the query is using * and could return more than the three
listed columns.
It is possible to leave out the type information for all or some of the scalars.
sess.createSQLQuery("SELECT * FROM CATS")
.addScalar("ID", Hibernate.LONG)
.addScalar("NAME")
.addScalar("BIRTHDATE")
This is essentially the same query as before, but now ResultSetMetaData is used to determine the type of NAME and BIRTHDATE, where as the type of ID is explicitly specified.
How the java.sql.Types returned from ResultSetMetaData is mapped to Hibernate types is controlled by the Dialect. If a specific type is not mapped, or does not result in the expected type, it is possible to customize it via calls to registerHibernateType in the Dialect.
An easy example what addScalar is used for:
public byte[] getFile(Integer id){
Query q = session
.createSQLQuery("select some_file from tbl_name where id=:id")
.addScalar("some_file", StandardBasicTypes.BINARY);
q.setInteger("id", id);
return (byte[]) q.uniqueResult();
}
For example you have blob data type in your database, in this case you can easily cast your result into byte[] but if you run the query without the addScalar function you will get your result as a blob and you can't cast blob to byte[] directly, you need to write a code for conversion:
try{
Blob blob =(Blob)q.uniqueResult();
int blobLength = (int) blob.length();
byte[] blobAsBytes = blob.getBytes(1, blobLength);
return blobAsBytes;
} catch (Exception e) {
return null;
}
In this problem, it's much easier to use addScalar.
As far as I now, it is not necessary. I've never, ever, written a query with .addScalar.
You could simply replace that with something like:
Query q = sessionFactory.getCurrentSession().createQuery(
"select b.band_id " +
"from guest_band as b "
);
List idList = q.list();
Although this may depend on how your entities are set up, it should work.
Perhaps .createSQLQuery and .createQuery are different in this manner.
Refer to this post on what the .addScalar() actually does: What does addScalar do?
Edit: I am familiar with Java, and I guess I was assuming you were using Java for your post. If using C# this may be different.

java.lang.String cannot be cast HQL

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.

Categories