I have written a code like this to fetch data from database using HQL:
Query qr=sess.createQuery("select i.contract_Vcode,i.installment_date from Installment i where i.vcode=:instalVcode").setParameter("instalVcode", installVcode);
qr.getNamedParameters();
List<Installment> li=null;
li=qr.list();
int coVcode=li.get(0).getContract_Vcode();
As I know the contract_Vcode is an integer. But when I want to run it, the followed error happens:
Error invoking Action using Hibernate Core Session / Transaction injection
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to information.Installment
More over when I want to see the exact element like this,
System.out.println("contract installDate is: "+li.get(0).getContract_Vcode());
Same error happens. How can I fix this?
You're currently only querying two parts of an installment. If you want to fetch the whole thing, I'd expect something like:
Query qr = sess.createQuery(
"select from Installment as i where i.vcode=:instalVcode")
.setParameter("instalVcode", installVcode);
If you fetch multiple properties (instead of whole entities), you just get back an Object[] for each row in the results.
So you could use your original query, but:
List<Object[]> li = qr.list();
int coVcode = (Integer) li.get(0)[0]; // 1st column of 1st row
Related
I am using Spring Boot endpoints to return results from database queries. It works fine when using getResultList() on the TypedQuery. However I know I will have to managed very large data sets. I am looking into using ScrollableResults via hibernate but I cannot figure out how to actually reference the contents of each row.
StatelessSession session = ((Session) entityManager.getDelegate()).getSessionFactory().openStatelessSession();
criteriaQuery.multiselect(selections);
criteriaQuery.where(predicates.toArray(new Predicate[]{}));
Query<?> query = session.createQuery(criteriaQuery);
query.setMaxResults(5);
query.setFetchSize(1000);
query.setReadOnly(true);
ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY);
while(results.next()){
Object row = results.get();
}
results.close();
session.close();
I have tried results.get(0), results.get(0)[0], results.getLong(0), Object[] row vs Object row, etc. With and without toString() on all of the options. Nothing I do gets more out of the row than the java object reference. I've tried casting as well and get a "cannot cast error". Sometimes I get an error, "query specifies a holder class". Not sure what that means because my criteria query is built by joining 1 or more entities where the entities and selected columns are not known before hand. So I am not actually specifying a class. They entities and selects are specified by user input. Any thoughts? Thanks!
UPDATE:
I can do System.out.println(scroll.getType(0)); and in this case observe a long.
But when I try to save that long (.getLong(0)) I get the error, "query specifies a holder class". Or again the cannot cast error.
Got it figured out. queryDetails is a CriteriaQuery<Tuple>
StatelessSession session = entityManagers.get("DatasourceName").unwrap(Session.class).getSessionFactory().openStatelessSession();
Stream<Tuple> resultStream = session.createQuery(queryDetails)
.setReadOnly(true)
.setMaxResults(100)
.setFetchSize(1000)
.setCacheable(false)
.getResultStream();
Iterator<Tuple> itr = resultStream.iterator();
while (itr.hasNext()){
//Get the next row:
Tuple row = itr.next();
}
A CriteriaQuery that uses multiselect produces an Object[] or javax.persistence.Tuple as result type. Maybe you should try debugging to see the actual object type and from there you can work further.
If you are processing and returning all rows anyway, there is no need to use the ScrollableResults API as you will have to create objects for all rows anyway. If your use case is to do some kind of aggregation, I would recommend you use an aggregate function instead and let the database do the aggregation.
Hi can anyone tell me why this java query is failing?
Query q = entityManager.createNativeQuery("SELECT m.* FROM MdmAudit m WHERE m.correlationID = :correlationId AND m.verb = :verb", MdmAuditDAO.class);
//Query q = entityManager.createNamedQuery("MdmAuditDAO.GetData");
q.setParameter("correlationId", resp.getHeader().getCorrelationID());
q.setParameter("verb", resp.getHeader().getVerb());
long result = (long) q.getFirstResult();
The namedQuery:
#NamedQuery( name="MdmAuditDAO.GetData", query="SELECT m FROM MdmAuditDAO m WHERE m.correlationId = :correlationId AND m.verb = :verb")
public class MdmAuditDAO implements Serializable {
I have getters and setter in my MdmAuditDAO class, and I have checked the naming of the variables, and they are identical as in the NamedQuery, so the problem does not lie there.
My problem is that I have three entries in my database, I should at least get one answer back but I get 0 in my result.
MdmAuditDAO is defined in my persistence.xml and in my ehcache.xml. So why is it that the result I get returned is 0? I have also tried to get an object returned or a list of objects, and it is the same result, nothing gets returned, but when I run my query in my mssql database I get results see picture below. It has nothing to do with the m.* I aslo get results when I use that in my SELECT statement.
EDIT 1: This is what I get from my hibernate log, and I do not know how to read this?
Hibernate:
select
mdmauditda0_.id as id1_7_,
mdmauditda0_.correlationID as correlat2_7_,
mdmauditda0_.messageID as messageI3_7_,
mdmauditda0_.meter_no as meter_no4_7_,
mdmauditda0_.noun as noun5_7_,
mdmauditda0_.payload as payload6_7_,
mdmauditda0_.source as source7_7_,
mdmauditda0_.subtype as subtype8_7_,
mdmauditda0_.time as time9_7_,
mdmauditda0_.verb as verb10_7_
from
MdmAudit mdmauditda0_
where
mdmauditda0_.correlationID=?
Anything I have to set, to get more information? I am using the following jars
And my java version is 1.7.0_79.
I found the solution http://www.objectdb.com/api/java/jpa/Query/getFirstResult returns the position of the first element, but I was a bit confused by the phrase
Returns 0 if setFirstResult was not applied to the query object.
Could not get my head around it to make any sense of it.
My solution now is that I just return a list of objects
Query q = entityManager.createNativeQuery("SELECT m.* FROM MdmAudit m WHERE m.correlationId = :correlationId AND verb = :verb", MdmAuditDAO.class);
//Query q = entityManager.createNamedQuery("MdmAuditDAO.GetData");
q.setParameter("correlationId", resp.getHeader().getCorrelationID());
q.setParameter("verb", resp.getHeader().getVerb());
List<MdmAuditDAO> mdmAuditList = q.getResultList();
And then it works fine and I get results. So instead of the the result == 0 check I am doing later in my code I just do a NULL and isEmpty() check instead().
Side note: I have not tried to delete entries and then see what the result would be then in the q.getFirstResult() call but that would be a possibility and see what i get returned and then check on that value, properbly null?
I am using an hibernate NQL query which fetches me two columns :
SELECT object_name,
object_name_location
FROM dbo.object_stacks
WHERE object_id IN (SELECT thumb_nail_obj_id
FROM dbo.uois
WHERE Upper(NAME) LIKE Upper('%testobj%'))
When I select only one column i.e only object name - everything works fine but with two columns I am getting an error
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to
java.lang.String
at run time when I try to display result from the list. I tried using String array in the list as well but it doesn't work. Below are my code snippets which give error :
When I use only List :
List<String> Thumbnailpaths = pathquery.list();
System.out.println(Thumbnailpaths.get(i).replace("\\", "\\\\"));
No error at compile time also nothing if leave it as it is but above line to display gives classcast exception.
When I use List array :
List<String[]> Thumbnailpaths = pathquery.list();
System.out.println(Thumbnailpaths.get(i)[0].replace("\\", "\\\\"));
Here again classcast exception at runtime
Also Criteria.ALIAS_TO_ENTITY_MAP doesn't help at all as it makes logic much more complex. I just need 2 column values from a database table.
Please let me know if there is any solution to fetch multiple column results in NQL and then put in list.
Note : Looks like here generics are not displaying and only List is being written in my code snippet
Yes, hibernate will return the Object arrays (Object[]) for this case - return multiple columns. but you still can using the "Entity queries" to return a entity objects rather then the "raw" value.
Unfortunately, Hibernate doesn't provide a standard way to retrieve the results for columns of table and store directly to Entity Object.You have to manually parse the data fetched by your query.
The hibernate query will return List of Object Array i.e. List<Object[]>.
Object[] will contain data from your columns. List is nothing but rows retrieved by query. In your case you can refer following code :
List<Object[]> Thumbnailpaths = pathquery.list();
for(Object[] objArr : Thumbnailpaths)
{
String objName = (String)objArr[0];
String objNameLocation = (String)objArr[1];
System.out.println(objName + " : " +objNameLocation);
}
Above code will help you parse the object[]
I'm coming back to Java after a few years away and this is my 2nd day looking at hibernate and don't fully understand it yet.
I have the following criteria which is performing a join:
Criteria cr = s.createCriteria(Bla.class, "bla");
cr.setFetchMode("bla.nodePair", FetchMode.JOIN);
cr.createAlias("bla.nodePair", "node_pair");
cr.add(Restrictions.in("bla.blaName", (List<Bla>) getBlas()));
ProjectionList columns = Projections.projectionList()
.add(Projections.property("node_pair.priNode"))
.add(Projections.property("bla.blaName"))
.add(Projections.property("node_pair.secNode"))
.add(Projections.property("bla.port"));
cr.setProjection(columns);
List<Object[]> list = cr.list(); // Exception occurs here
This is creating as far as I can tell a valid SQL query and exactly what i'm after.
However, when I try to generate a list of results cr.list(); I get:
java.lang.ClassCastException: com.some.package.domainobject.Bla cannot be cast to java.lang.String
How should I construct my List. Any pointers much appreciated.
In Criteria API, the Exception is always(?) thrown when attempting to get the results.
In your case, the problematic line is probably
cr.add(Restrictions.in("bla.blaName", (List<Bla>) getBlas()));
You seem to check if a java.lang.String is part of a Collection<Bla>.
If your equals and hashcode methods in Bla use the blaName field, you should be able to use
cr.add(Restrictions.in("bla", (List<Bla>) getBlas()));
Otherwise, implements a getBlasNames() function which returns a List<String>
I am trying to execute the following query:
select MAX(CAST(T.progress AS DECIMAL)) as maxProgress from default_APN_TRACKING T where T.smartlet = 'Life-Pension Selector' GROUP BY T.trackingId
Which throws me the following Exception:
java.lang.Exception: Exception on sql query:select MAX(CAST(T.progress AS DECIMAL)) as maxProgress from default_APN_TRACKING T where T.smartlet = 'Life-Pension Selector' GROUP BY T.trackingId
Basically, i got a table with tracking IDs, and a string representing the progresses ("100.0", "66.6", "33.3", ...). For each trackingId, i want to get the highest progress.
I Agree having Integers would make more sens, but it's a constraint I have to deal with. So i tried using the CAST. Also Attempted CAST(T.progress AS DECIMAL(10,5)) without success.
The same query without the CAST works just fine, but sorts alphanumerically ("66.6" > "100.0"). How should I tackle this problem?
Thanks for the help!
EDIT: Copying the same query directly inside SQL WorkBench works perfectly. Seems like Java.sql does not like my query for some reason.