如何使用Hibernate session.createSQLQuery()来使用JOIN

时间:2011-01-14 19:31:45

标签: java hibernate jpa hibernate-entitymanager

我有两个实体(表格) - 员工&项目。员工可以拥有多个项目。 项目表的CREATOR_ID字段引用Employee表的ID字段。员工实体不维护项目的任何参考 - 但项目实体具有员工的参考。

使用EntityManager以下查询工作正常 -

entityManager.createQuery(
    "select e from EmployeeDTO e, ProjectDTO p"
    + " where p.id = ?1 and p.creator.id=e.id");

但由于我有LAZY关联关系,我收到错误:

  

无法初始化代理 - 没有   会话

如果我尝试从Employee实体访问项目信息。这是预期的,因此我使用Hibernate的Session来创建查询,如下所示。

Session session = HibernateUtil.getSessionFactory().openSession();
org.hibernate.Query q = session.createSQLQuery(
    "SELECT E FROM EMPLOYEE_TAB E, PROJECT_TAB P  WHERE P.ID = "
    + projectId + " AND P.CREATOR_ID = E.ID")
    .addEntity("EmployeeDTO ", EmployeeDTO.class)
    .addEntity("ProjectDTO", ProjectDTO.class);

但我得到的错误如下:“列'E'要么不在FROM列表中的任何表中,要么出现 在连接规范中,并且超出了连接规范的范围......“

有谁可以建议这种情况下正确的JOIN语法是什么?如果我使用("SELECT * FROM EMPLOYEE_TAB E, ........") - 它会出现其他错误:

  

java.lang.ClassCastException:   [Ljava.lang.Object;无法施展   com.im.server.dto.EmployeeDTO

提前致谢。

2 个答案:

答案 0 :(得分:1)

加载ProjectDTO时,您不需要使用本机SQL查询来预取EmployeeDTO。您的原始查询可以更优雅的方式重写,如下所示:

select e from EmployeeDTO e join e.projects p where p.id = ?1

然后,您可以添加join fetch子句以预取项目:

select distinct e from EmployeeDTO e join e.projects p join fetch e.projects where p.id = ?1

另见:

答案 1 :(得分:0)

您的SQL以SELECT E from EMPLOYEE E ...开头,您的意思是SELECT E.*, P.* from EMPLOYEE E ...吗?