JPA如何加入这些实体

时间:2013-05-29 08:14:48

标签: java sql jpa

鉴于以下JPA实体,我希望所有具有至少一个成功状态的请求的借记。

可以有许多具有相同debit_id和不同状态的请求

我应该使用这样的东西还是有更好的做事方式

entityManager.createQuery(“从借记d中选择c加入d.id,其中request.status =成功”

@Entity(name = "T_DEBIT")
public class Debit {
  public enum Status { NEW, OLD } 

  @Column(name = "STATUS", nullable = false, length = 20)
  @Enumerated(value = EnumType.STRING)
  private Status status;
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "ID")
  private Long id;

  @ManyToOne(optional = false)
  @JoinColumn(name = "ACCOUNT_ID", updatable = false, nullable = false)
  private Account account;

}

和其他实体是

@Entity(name = "T_REQUEST")
public class Request{  

  public enum Status { PENDING, FAILED, SUCCESFUL}  

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "ID")
  private Long id;

  @ManyToOne(optional = false)
  @JoinColumn(name = "DEBIT_ID", updatable = false, nullable = false)
  private Debit debit;

  @Column(name = "STATUS", nullable = false, length = 20)
  @Enumerated(value = EnumType.STRING)
  private Status status;

 }

如果遗漏了任何内容而不是关闭或低估问题,请发表评论!

1 个答案:

答案 0 :(得分:2)

基本上:

select d
from T_DEBIT d
where exists (
    select r
    from T_REQUEST r
    where 
    r.debit.id = d.id and
    r.status = SUCCESSFUL
)

检查JPQL中的枚举语法,我通常不使用枚举实体,在这个例子中可能是错误的。

作为样式问题,我会使实体名称==类名而不是实体名==表名。这使得事实上JPQL SQL更清晰

<强>更新

Spring要求解决类似的问题。解决这些问题的方法非常系统:

a)仅使用基本过滤器和以下表达式重写您的问题:

  1. “存在一些......条件成真”
  2. “for all ... condition is true”
  3. b)翻译:

    1. 此案例变为exists (select ... where condition)
    2. 此案例变为not exists (select ... where NOT condition)
    3. 在Spring的特定问题中,“排除所有成功请求”,目标不是很明确。如果他/她的意思是“在没有成功请求的情况下获得所有借记”,那么您可以这样做:

      a)将问题重写为“获取所有相关请求的所有借记,请求状态不成功”。 b)翻译为

      select d
      from T_DEBIT d
      where not exists (
          select r
          from T_REQUEST r
          where 
          -- This is the join condition, so it should not be negated
          r.debit.id = d.id and 
          -- This is the actual filtering condition, negate as this is a FOR ALL
          not (r.status != SUCCESSFUL)
      )
      

      然后你可以简化最后一个条件,获得:

      select d
      from T_DEBIT d
      where not exists (
          select r
          from T_REQUEST r
          where 
          r.debit.id = d.id and
          r.status = SUCCESSFUL
      )