如何在JPA中使用3个JOIN编写SQL SELECT?

时间:2013-10-22 08:04:01

标签: sql jpa ejb entity jpql

我有实体:

@Entity(name = "sent_message")
public class SentMessage extends AbstractEntity {
    @ManyToOne(fetch = FetchType.LAZY)
    private TargetGroup targetGroup;
    @ManyToOne(fetch = FetchType.LAZY)
    private Customer customer;
    @ManyToOne(fetch = FetchType.LAZY)
    private MessageTemplate template;
    private Date sentDate;
    getter.setter...
}

@Entity(name = "target_group")
public class TargetGroup extends AbstractEntity {
    private String name;
    private String description;
    @ManyToMany(fetch = FetchType.LAZY)
    private List<Customer> customers = new ArrayList<>();
    getter.setter...
}

@Entity(name = "customer")
public class Customer extends AbstractEntity {
    private String name;
    private String email;
    private String mobile;
    @ManyToMany(mappedBy="customers", fetch = FetchType.LAZY)
    private List<TargetGroup> targetGroups = new ArrayList<>();
    @OneToMany(mappedBy = "customer", fetch = FetchType.LAZY)
    private List<SentMessage> sentMessages = new ArrayList<>();
    getter.setter...
}

@Entity(name = "message_template")
public class MessageTemplate extends AbstractEntity {
    private String subject;
    private String text;
    @OneToMany(mappedBy = "template", fetch = FetchType.LAZY)
    private List<SentMessage> sentMessages;
    getter.setter...
}

我希望TargetGroup,Customer,MessageTemplate成为查询的结果。我的选择:

SELECT msg FROM SentMessage msg JOIN msg.targetGroup tg, msg.customer cust, msg.template temp WHERE ....

这是正确的,还是应该怎么写?我想要所有实体的所有参数。 谢谢!

编辑:我想搜索TargetGroup的名称,客户名称和其他人,我应该如何在WHERE中编写?

1 个答案:

答案 0 :(得分:1)

您必须在查询的select子句中列出所需的结果:

SELECT msg.targetGroup, msg.customer, msg.template FROM SentMessage msg 

您将获得包含数据的Object[]

如果由于延迟提取而遇到问题,可以添加提取连接以检索相关实体:

SELECT msg.targetGroup, msg.customer, msg.template FROM SentMessage msg join fetch msg.targetGroup tg join fetch  msg.customer cust join fetch msg.template temp

编辑您的评论表明您还需要结果中的“父”消息。在这种情况下,创建投影查询(列出select子句中的所有属性)没有意义。只需获取父消息并调用常规getter即可访问CustomerTargetGroup和其他关联。如果出现延迟提取问题,请使用提取连接。

SELECT msg FROM SentMessage msg 

SELECT msg FROM SentMessage msg join fetch msg.targetGroup tg join fetch  msg.customer cust join fetch msg.template temp

编辑2 为了向查询添加约束,您可以添加引用任何id变量的常规where子句:

... join fetch  msg.customer cust where cust.name = :cust_name... 

然而,fetch连接的行为与where子句有点意外 - fetch也受where子句的限制。请参阅this thread以获取参考