JPA:在 JPQL 中加入

Posted

技术标签:

【中文标题】JPA:在 JPQL 中加入【英文标题】:JPA: JOIN in JPQL 【发布时间】:2011-04-13 10:29:55 【问题描述】:

我以为我知道如何在JPQL 中使用JOIN,但显然不知道。谁能帮帮我?

select b.fname, b.lname from Users b JOIN Groups c where c.groupName = :groupName

这给了我例外

org.eclipse.persistence.exceptions.JPQLException
Exception Description: Syntax error parsing the query
Internal Exception: org.eclipse.persistence.internal.libraries.antlr.runtime.EarlyExitException

UsersGroups 具有 OneToMany 关系。

Users.java

@Entity
public class Users implements Serializable

    @OneToMany(mappedBy="user", cascade=CascadeType.ALL)
    List<Groups> groups = null;

Groups.java

@Entity
public class Groups implements Serializable 
    @ManyToOne
    @JoinColumn(name="USERID")
    private Users user;

我的第二个问题是假设这个查询返回一个唯一的结果,那么如果我这样做了

String temp = (String) em.createNamedQuery("***")
    .setParameter("groupName", groupName)
    .getSingleResult();

*** 表示上面的查询名称。那么fnamelnametemp 内连接在一起还是我得到一个List&lt;String&gt; 回来?

【问题讨论】:

【参考方案1】:

在 JPQL 中加入一对多关系如下所示:

select b.fname, b.lname from Users b JOIN b.groups c where c.groupName = :groupName 

select子句中指定了多个属性时,结果返回为Object[]

Object[] temp = (Object[]) em.createNamedQuery("...")
    .setParameter("groupName", groupName)
    .getSingleResult(); 
String fname = (String) temp[0];
String lname = (String) temp[1];

顺便说一句,为什么您的实体以复数形式命名,这令人困惑。如果你想用复数形式的表名,你可以使用@Table明确指定实体的表名,这样就不会干扰保留字:

@Entity @Table(name = "Users")     
public class User implements Serializable  ...  

【讨论】:

如果不是选择字段,而是选择一个实体 + 另一个实体的字段,该怎么办。类似于SELECT b , c.name ...。那么 Object[] 中的第一个对象将是 b 的字段还是整个实体?

以上是关于JPA:在 JPQL 中加入的主要内容,如果未能解决你的问题,请参考以下文章

JPA JPQL简介

直接在 JPA / JPQL 中将行插入连接表?

JPA JPQL高级操作

如何过滤 JPA/JPQL 中的集合?

Spring Boot JPA:为同一参数传递多个值 (JPQL)

使用 JPQL/HQL 在 JPA 中订购连接获取的集合