如何重写JPQL中子查询条件的位置

问题描述 投票:0回答:1

在我的模型中存在一对多的关系,包括主实体和细节实体。我需要构造持久性查询,以便只查询那些具有特定细节行的主行。

我编写了像本机SQL查询一样的持久性查询,但它似乎不是最佳的。

简化的主实体

@Entity
@Table(name = "SED_JMS_REQUESTS")
public class JMSRequest{

@Id
private Long id;

@OneToMany(fetch = FetchType.EAGER,
        targetEntity=JMSAction.class, mappedBy="ownerRequest")
private Set<JMSAction> sedJMSActions;

@Column(name = "REQUEST_ACTION")
@Min(1)
private Integer requestAction;    
...
}

简化细节实体

@Entity
@Table(name = "SED_JMS_ACTIONS")
public class JMSAction{
    @Id
    private Long id;

@ManyToOne(fetch= FetchType.LAZY)
@JoinColumn(name = "REQUESTID")
private JMSRequest ownerRequest;

@Column(name = "REQUESTID",insertable=false,updatable=false)
private Long requestId;

@Basic(optional = false)
@Column(name = "REQUEST_ACTION")
private Integer requestAction;
...
}

适当的本机SQL查询,这是有效的

select * from SED_JMS_requests r
where (select nvl(sum(a.request_Action),0) from SED_JMS_ACTIONS a where a.requestid=r.id and a.status=1) = r.request_Action

构造的持久性查询类似于上面的本机SQL查询

select r From JMSRequest r where  ((select NVL(SUM(a.requestAction),0) from JMSAction a where a.requestId = r.id and a.status=1) != r.requestAction) 

我编写了持久性查询,它与原生SQL查询类似。它是有效的,但对我来说它并不是最佳的,因为细节实体已经加入,因为@ManyToOne正在热切地获取。因此,生成的持久性查询包含两次详细实体,一次作为连接实体,再次包含where条件。

java hibernate jpa jpa-2.0 jpql
1个回答
1
投票

在JPQL中,您可以像这样加入相关的实体:

SELECT r FROM JMSRequest r
JOIN r.sedJMSActions a
WHERE a.status=1
GROUP BY r.id
HAVING SUM(a.requestAction)!=r.requestAction
© www.soinside.com 2019 - 2024. All rights reserved.