3

我最初的问题是https://stackoverflow.com/questions/12172614/hql-join-without-foreign-key-reference 但找不到任何解决方案,因此使用 JPA 进行本机查询。entityManager 的 createNativeQuery 返回 Query 对象,该对象又返回List<Object[]>. 我不想在迭代列表时处理索引,因为它本质上容易出错。因此,我查看了其他一些解决方案,并发现 JPQL 的构造函数表达式作为解决方案之一。

表结构是

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']

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

4

1 回答 1

8

根据“Pro EJB 3 Java Persistence API”一书

构造函数表达式

涉及多个表达式的更强大的SELECT子句形式是构造函数表达式,它指定查询的结果将使用用户指定的对象类型来存储。考虑以下查询:

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

此查询的结果类型是 type example.EmployeeDetails。当查询处理器迭代查询结果时,它会实例化EmployeeDetails使用与查询中列出的表达式类型匹配的构造函数的新实例。在这种情况下,表达式类型是 String、Double 和 String,因此查询引擎将搜索具有这些类类型的构造函数作为参数。因此,生成的查询集合中的每一行都是一个 EmployeeDetails包含员工姓名、薪水和部门名称的实例。

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

构造函数表达式是构建粗粒度数据传输对象或视图对象以供其他应用程序层使用的强大工具。无需手动构建这些对象,可以使用单个查询将视图对象聚集在一起,以便在网页上呈现。

示例代码如下

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,没有注释,但有正确的构造函数来匹配构造函数表达式。结果是返回的每一行的 EmpMenu 对象列表。

我相信您的 SQL 部分“....来自 Schema1.TableA ms ..”应该指的是映射的实体。因此,您应该将实体映射到 TableA,然后 jpql 应该更像“.... From MyTableAEntity ms ...”的内容,其中 MyTableAEntity 具有将其映射到 DB 表 TableA 的所有正确 jpa 注释。正如书摘所述,“SELECT NEW ...”的目标不必映射,但 FROM 子句中引用的实体却可以。

于 2012-09-05T16:55:49.620 回答