问题
When I use list() of Hibernate (HQL) after createQuery(), then I want to directly type cast List<Object[]> to my List<POJO class>. I describe my actual scenario here. I have 3 Plain Old Java Objects say Person, Operation and Project and a table say Transaction with foreign references to Person , Operation and Project.
class Person {
String name;
// getters and setters
}
class Operation {
String name;
// getters and setters
}
class Project {
String name;
// getters and setters
}
class Transaction {
String p_id;
String o_id;
String project_id;
// refers to id of All three table above
}
Now, I want to execute a Hibernate Query Language query say
String query="select p.name, o.name, project.name from Person p , Operation o, Project project , Transaction t where p.id=2 and p.id=t.p_id and o.id=t.o_id and project.id=t.project_id".
I have created a Model class for output of this query say POP_Model.
private class POP_Model {
String person_name;
String operation_name;
String project_name;
}
Now, I want to use Hibernate query:
Session session=HibernateConnection.getSessionFactory().openSession();
Query q=session.createQuery(query);
List<POP_Model> list=(List<POP_Model>)q.list();
It gives typecast error saying Object[] cannot be converted to POP_Model. I checked out TypedQuery but didn't get an example for it. But as far as I know, TypedQuery can be used to map to POJO not Model. I want to directly type cast to Model.
回答1:
If you are OK with using the JPA API (which Hibernate implements as well) instead of the Hibernate API for this, you can use JPQL constructor queries:
List<DTO> dtos = entityManager.createQuery("SELECT NEW com.example.DTO( p.name, o.name) FROM Entity o").getResultList();
EDIT It looks like Hibernate implements constructor expressions with it's regular API as well:
List<DTO> dtos = session.createQuery("SELECT NEW com.example.DTO( p.name, o.name) FROM Entity o").list();
EDIT2 JPA is a Java EE standard, unifying working with different persistence libraries like Hibernate and EclipseLink. The oracle tutorial is quite decent.
You can retrieve an EntityManager in a non-EE application like this:
@PersistenceUnit
private EntityManagerFactory emf;
...
EntityManager em = emf.createEntityManager();
回答2:
First create a constructor on the POJO class.
private class POP_Model {
String person_name;
String operation_name;
String project_name;
public POP_Model(String person_name, String operation_name, String project_name){
this.person_name = person_name;
this.operation_name = operation_name;
this.project_name = project_name;
}
}
Then you can use
select new com.server.dtos.POP_Model(p.name, o.name, project.name)
from Transaction t INNER JOIN t.operation o
INNER JOIN t.person p
INNER JOIN t.project project
where p.id=2
For Reference, here is the official documentation. Go through New object with HQL as well.
来源:https://stackoverflow.com/questions/15339504/hibernate-hql-createquery-list-type-cast-to-model-directly