Java: Retrieve results from Persistence Query Language using List - java

Im querying a database using JPQL but I cannot retrieve the 'Report' table's rows using List. This is a section of my code:
...
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hibernate");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Query query = em.createQuery("SELECT r.title, r.company FROM Report as r");
List<Report> itemList = query.getResultList();
for (Report item : itemList)
{
System.out.println("Item: " + item.getCompany());
}
The output is:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to maps.Report at hello.Test.main(Unknown Source)
Java Result: 1
What am I doing wrong? Why I am not allowed to do the casting?

Your query doesn't select instances of Report. It selects two fields: r.title and r.company. In this case, JPA returns a list of Object[]. Each Object[] of the list contains two elements: the title and the company.
Use select r from Report r to select Report instances.

You need to create a TypedQuery.
String sql = "select r from Report r";
TypedQuery<Report> query = em.createQuery(sql, Report.class);
List<Report> reports = query.getResultList();

Related

count(distinct( with an EntityManager

i have an issue with my EntityManager.
Comparing, core-SQL with java EntityManager, i do not observe the sames comportments.
in core-SQL (OK)
select count (distinct p.product_id) from product p ;
equivalent with an EntityManager (OK)
Query c = entityManager.createQuery("select
count(distinct(p.productId))
from product p");
but now, with two arguments, i got an issue :
in core-SQL (OK)
select count (distinct (p.product_id , p.product_name)) from product p ;
equivalent with an EntityManager = KO !!!!
Query c = entityManager.createQuery("select
count(distinct(p.productId, p.productName))
from product p");
EntityManager does not accept two arguments in the distinct clause.
i got an exception
antlr.NoViableAltException: unexpected AST node: {vector}

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to className

Code:
public void getDetails() {
try {
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
String hql = "select c.mobile, c.password FROM CrbtSubMasterDemo c where rownum<20";
Query query = session.createQuery(hql);
List<CrbtSubMasterDemo> itr = query.list();
session.getTransaction().commit();
for (CrbtSubMasterDemo pojo : itr) {//excepion line
System.out.println("[" + pojo.getMobile() + "]");
}
} catch (Exception e) {
e.printStackTrace();
}
}
CrbtSubMasterDemo is pojo mapped with the db.
When I try to run it, it gives following Exception:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.telemune.demoPojo.CrbtSubMasterDemo
at com.telemune.demoHibernate.QueryTester.getDetails(QueryTester.java:57)
at com.telemune.demoHibernate.QueryTester.main(QueryTester.java:23)
The question is query.list() is returning the list of objects of pojo class. Then why is this Exception. I am new to Hibernate, sorry if its a silly question.
When you write this:
String hql = "select c.mobile, c.password FROM CrbtSubMasterDemo c where rownum<20";
Your result set is not a List of CrbtSubMasterDemo
Try to write:
String hql = "select FROM CrbtSubMasterDemo c where rownum<20";
Another way is define a new constructor of CrbtSubMasterDemo where you pass only two fields c.mobile, c.password
so your query becomes:
String hql = "select new " + CrbtSubMasterDemo.class.getName() + "(c.mobile, c.password) FROM CrbtSubMasterDemo c where rownum<20";
If you follow this solution, remeber to add a default constructor too (without parameters), so in your pojo you have:
public CrbtSubMasterDemo(String mobile, String password) {
this.mobile = mobile;
this.password = password
}
and
public CrbtSubMasterDemo() {
}
String hql = "select c.mobile, c.password FROM CrbtSubMasterDemo c where rownum<20";
Query query = session.createQuery(hql);
Result of this will be List<Object[]>
List<Object[]> itr = query.list();
for (Object[] row : itr) {
System.out.println(String.format("mobile:%s, password:%s", row[0], row[1]));
}
if mobile and password are strings, of course. You can use a transformer to transform results directly to CrbtSubMasterDemo.
Hibernate 3.2: Transformers for HQL and SQL
FluentHibernateResultTransformer
Sir, Many times user faces this kinda requirements . Hibernate has ResultTransformer to convert a hql/sql in Object.
public CrbtSubMasterDemo{
private Stirng mobile;
private String password;
public CrbtSubMasterDemo(){
--------------
}
#####after setting the transation set whichever columns you are selecting should be given as name of property of your object
String hql = "select c.mobile as mobile, c.password as password FROM CrbtSubMasterDemo c where rownum<20";
Query query = session.createQuery(hql);
List<CrbtSubMasterDemo> itr = query.setResultTransformer(Transformers.aliasToBean(CrbtSubMasterDemo.class) ).list();
##No need to commit the transaction.
}
It will convert you query into the CrbtSubMasterDemo
Do not directly cast the result of "query.list();" to List of CrbtSubMasterDemo. As query.list() return object list. Iterate over the object list received and cast one by one to put in list List of CrbtSubMasterDemo

How does a native sql query bind fields to an entity instead of map

I tried to run native sql query with resulttransformer (AliasToBeanResultTransformer), it gives error like below.
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: com.ozpas.ozentegre.entity.EntDevirlog cannot be cast to java.util.Map
at org.hibernate.property.access.internal.PropertyAccessMapImpl$SetterImpl.set(PropertyAccessMapImpl.java:102)
at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:78)
By the way, my native sql query does not include all fields in the entity ( EntDevirlog ), there are only some fields in that entity. shall the query include all fields in the entity ?
as i understood, hibernate transforms result into a map object instead EntDevirlog entity. It uses PropertyAccessMapImpl. how can i solve this problem to get the result as a list ( arraylist ) ? thanks.
Session session = HibernateUtilMikro.getSessionFactory().openSession();
List<EntDevirlog> results = new ArrayList<EntDevirlog>();
Transaction tx = null;
String sql = "mynativequery";
SQLQuery query = session.createSQLQuery(sql);
query.setParameter("tarih", tarih);
query.setParameter("srmkodu", srmkodu);
query.setParameter("s1", EnumPanoislemtipleri.islem1.getValue());
query.setParameter("s2", EnumPanoislemtipleri.islem2.getValue());
query.setResultTransformer(new AliasToBeanResultTransformer(EntDevirlog.class));
results = query.list();
tx.commit();
Just use the quotes for the aliases
"select firstName as \"firstName\",
lastName as \"lastName\" from Employee"
Read for a more deeply explanation here:
mapping Hibernate query results to custom class?

Is there any spring jpa equivalent to following query

Query :
#Query("Select p.name,t.points from Player p,Tournament t where t.id=?1 And p.id=t.player_id")
I have my player and tournament entity and their corresponding JPA repositories. But the problem is we can get only entities from our query, but i want to do above query, please help me with this i am new to it.
this is my sql query i want to add but where to add i am not getting:
Select p.name, t.points_rewarded from player p, participant t where t.tournament_id="1" and t.player_id=p.id;
This is how you can do it with JPQL for JPA:
String queryString = "select p.name, t.points from Tournament t," +
" Player p where t.player_id=p.id " +
"and t.id= :id_tournament";
Query query = this.entityManager.createQuery(queryString);
query.setParameter("id_tournament", 1);
List results = query.getResultList();
You can take a look at this JPA Query Structure (JPQL / Criteria) for further information about JPQL queries.
And this is ho you can do it using HQL for Hibernate, these are two ways of doing it:
String hql = "SELECT p.name, t.points from Player p,Tournament t WHERE t.id= '1' And p.id=t.player_id";
Query query = session.createQuery(hql);
List results = query.list();
Or using query.setParameter() method like this:
String hql = "SELECT p.name, t.points from Player p,Tournament t WHERE t.id= :tournament_id And p.id=t.player_id";
Query query = session.createQuery(hql);
query.setParameter("tournament_id",1);
List results = query.list();
You can take a look at this HQL Tutorial for further information about HQL queries.
Note:
In both cases you will get a list of Object's array List<Object[]> where element one array[0] is the p.name and the second one is t.points.
TypedQuery instead of normal Query in JPA
this is what i was looking for, thanks chsdk for help, i have to create pojos class, and in above link answer is working fine foe me,
Here is my code sample
String querystring = "SELECT new example.restDTO.ResultDTO(p.name,t.pointsRewarded) FROM Player p, Participant t where t.tournamentId=?1 AND t.playerId = p.id ORDER by t.pointsRewarded DESC";
EntityManager em = this.emf.createEntityManager();
try {
Query queryresults = em.createQuery(querystring).setParameter(1, tournamentId);
List<ResultDTO> result =queryresults.getResultList();
return new ResponseEntity<>(result, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
} finally {
if (em != null) {
em.close();
}}

Hibernate get List from database

In the following code I am trying to get a List of Products which contains all the products in the database:
public List<Products> getAllProducts() throws Exception{
try{
List<Products> products ;
org.hibernate.Transaction tx = session.beginTransaction();
products = session.createSQLQuery("SELECT * FROM Products").list();
if(products.size() > 0)
{
return products;
}
return null;
}
catch(Exception e)
{
throw e;
}
}
however this exception is thrown:
[Ljava.lang.Object; cannot be cast to mediatek.Products
List<Products> list = session.createCriteria(Products.class).list();
This will give you all the records of products table from database
Your answer not only adds a cast, but switches from SQL to HQL. Since your 2nd query is in HQL, Hibernate is able to use mapping information to know what class to return. This is the preferred way to do things in Hibernate, but if you had to use SQL for some reason you could achieve the same thing with:
(List<Products>)session.createSQLQuery("SELECT * FROM Products").addEntity(Products.class).list();
In Hibernate 5 the session.createCriteria methods are deprecated.
You will need to use a CriteriaBuilder and query from there to get a generic list of Products instead of just List.
Imports
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
Code
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Products> criteria = builder.createQuery(Products.class);
criteria.from(Products.class);
List<Products> products = session.createQuery(criteria).getResultList();
Forgot to type cast the query. it is working now.
List<Products> products = (List<Products>) session.createQuery("from Products").list();
For example you have code:
Session session = getSessionFactory().openSession();
Transaction transaction = null;
try {
SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM schema.yourtable WHERE param = :param");
sqlQuery.setString("param", "someParam");
And if your next step will be:
List list = sqlQuery.list();
You will receive list with Rows. You can see your Entity.class parameters in debug, but cat cast to List with your Entities:
List<Entity> list = (List<Entity>) sqlQuery.list();
In this point will be ClassCastException!
And if you need received List with your Entities you must add entity type to sql query:
List<Entity> list = (List<Entity>)sqlQuery.addEntity(Entity.class).list();
That's all. I hope someone will help.
if you using sql query, you should add this line at the last of the query to get the list you want:
.setResultTransformer(Transformers.aliasToBean(testDTO.class)).list();

Categories