JPQL构造函数expression式 – org.hibernate.hql.ast.QuerySyntaxException:表未映射

我原来的问题是https://stackoverflow.com/questions/12172614/hql-join-without-foreign-key-reference,但无法find任何解决scheme,因此前进使用JPA本地查询。 entityManager的createNativeQuery返回Query对象,然后返回List<Object[]> 。 我不想在迭代列表时处理索引,因为它本质上是错误的。因此,我查看了一些其他的解决scheme,并发现JPQL的构造器expression式作为解决scheme之一。

表结构是

 Schema1 -TableA - NameColumn - PhoneColumn 

对应的Java类是

  public class PersonSearch implements Serializable { public PersonSearch (String NameColumn, String PhoneColumn) { this.name = NameColumn; this.phone = PhoneColumn; } private String name; private String phone; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } } 

查询是

  Select NEW com.xyz.PersonSearch(ms.NameColumn, ms.PhoneColumn) From Schema1.TableA ms Where ms.PhoneColumn='9134409930' 

同时使用entityManager API运行这个查询

 entityManager.createQuery(queryString, PersonSearch.class); 

得到低于错误。

 Caused by: org.hibernate.hql.ast.QuerySyntaxException: Schema1.TableA is not mapped [Select NEW com.xyz.PersonSearch(ms.NameColumn, ms.PhoneColumn) From Schema1.TableA ms Where ms.PHONE='9134409930'] 

我的代码有什么问题? 任何想法 ?

根据“Pro EJB 3 Java持久性API”

构造函数expression式

涉及多个expression式的SELECT子句的更强大的forms是构造函数expression式,它指定查询的结果将使用用户指定的对象types进行存储。 考虑以下查询:

 SELECT NEW example.EmployeeDetails(e.name, e.salary, e.department.name) FROM Employee e 

这个查询的结果types是example.EmployeeDetailstypes。 当查询处理器遍历查询结果时,它使用匹配查询中列出的expression式types的构造函数实例化EmployeeDetails新实例。 在这种情况下,expression式types是String,Double和String,所以查询引擎将search具有这些types参数的构造函数。 生成的查询集合中的每一行都是EmployeeDetails一个实例,包含员工姓名,工资和部门名称。

必须使用对象的完全限定名称引用结果对象types。 但是,该类不必以任何方式映射到数据库。 任何具有与SELECT子句中列出的expression式兼容的构造函数的类都可以在构造函数expression式中使用。

构造函数expression式是用于构build粗粒度数据传输对象或查看其他应用程序层中使用的对象的强大工具。 而不是手动构build这些对象,可以使用一个查询来收集准备在网页上呈现的视图对象。

示例代码如下

 List result = em.createQuery("SELECT NEW example.EmpMenu(e.name, e.department.name) " + "FROM Project p JOIN p.employees e " + "WHERE p.name = ?1 " + "ORDER BY e.name").setParameter(1, projectName).getResultList(); 

EmpMenu类是一个简单的pojo,没有注释,但有正确的构造函数来匹配构造函数expression式。 结果是每个返回的行的EmpMenu对象列表。

我相信你的SQL的一部分“….从Schema1.TableA ms ..”应该指映射的实体。 所以你应该有一个映射到TableA的实体,然后jpql应该更多地沿着“…. MyTableAEntity ms …”行,其中MyTableAEntity具有所有适当的jpa注释映射到数据库表TableA。 正如书中所述,“SELECT NEW …”的目标不必被映射,但FROM子句中引用的实体却可以。