【问题标题】:Directionality in JPQL joins for Spring Boot JPA?JPQL 中的方向性加入 Spring Boot JPA?
【发布时间】:2018-01-18 16:09:12
【问题描述】:

这里是 Spring Boot。我有以下两个 JPA 实体:

@Entity
@Table(name = "accounts")
public class Account {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "account_id")
  private Long id;

  // lots of stuff

  @OneToOne(fetch = FetchType.EAGER, cascade = [CascadeType.PERSIST, CascadeType.MERGE])
  @JoinColumn(name = "profile_id", referencedColumnName = "profile_id")
  private Profile profile;    // CAN be null

  // Getters, setters & ctors
}

@Entity
@Table(name = "profiles")
public class Profile {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "account_id")
  private Long id;

  // doesn't really matter lots of stuff in here

  // Getters, setters & ctors
}

有些帐户可能有个人资料,有些则没有(他们的个人资料将为空)。我想创建一个 CrudRepository impl 来执行此查询:

SELECT *
FROM profiles p
INNER JOIN accounts a
WHERE a.profile_id = null

基本上,让我获得所有“孤立”并与此处的任何帐户相关联的个人资料。

我很困惑我是否需要 CrudRepository<Long,Account> impl 或 CrudRepository<Long,Profile> impl 以及该 impl 的外观。到目前为止,我最好的伪尝试如下:

public interface ProfileRepository extends CrudRepository<Profile, Long> {
    @Query("FROM Account act WHERE act.profile = null")
    public Set<Profile> findOrphanedProfiles();
}

谁能帮我填补空白?

【问题讨论】:

    标签: spring-boot spring-data-jpa jpql


    【解决方案1】:

    首先,JPQL NULL 检查语法是 IS NULL,而不是 == NULL(请参阅 JPQL docs - 该链接适用于 ObjectWeb,但适用于任何 JPA 实现)

    其次,如果你想检查孤立记录,你肯定不想加入他们孤立的表。

    你最后一次尝试,

    public interface ProfileRepository extends CrudRepository<Profile, Long> {
        @Query("FROM Account act WHERE act.profile = null")
        public Set<Profile> findOrphanedProfiles();
    }
    

    实际上非常接近,只需将 == null 替换为 is null 即可。

    编辑:如果您正在寻找没有与之关联的帐户的个人资料,EXISTS 查询就是您要寻找的:

    public interface ProfileRepository extends CrudRepository<Profile, Long> {
        @Query("FROM Profile p WHERE NOT EXISTS (FROM Account a WHERE a.profile = p)")
        public Set<Profile> findDisassociatedProfiles();
    }
    

    编辑:如果您的Profiles 维护关联帐户列表作为属性(它未包含在您发布的代码中,但可能被省略),您可以更短地查询未关联的配置文件:

    FROM Profile p WHERE p.accounts IS EMPTY

    【讨论】:

    • 谢谢@Alex (+1) 但那不会获取Set&lt;Account&gt;(所有具有空配置文件的帐户)吗?我正在寻找一个Set&lt;Profile&gt;,我知道它与任何帐户都没有关联...
    • @smeeb 由于您的帐户指向个人资料而不是相反,因此可以孤立帐户而不是个人资料。或者您实际上是在寻找没有任何帐户指向它们的个人资料?问题语义一定让我有点困惑,因为这不是“孤儿”通常的意思。我也会在我的回答中包含这个场景的查询
    • 谢谢@Alex 我会试一试的。每个“孤儿”,如果我在这里错了,请纠正我,但“孤儿”是没有父母的孩子。由于帐户可以拥有个人资料,因此我将它们视为父母,将个人资料视为孩子。因此,如果个人资料没有帐户(父级),则它是“孤儿”。没有?
    • @smeeb 通常,期望父母是关系的“一”方,而孩子是“多”方。当然,您可以颠倒含义,甚至完全采用不同的命名约定,但理解起来会违反直觉。请注意,在多对多关系的情况下,任何一方都可能成为“孤儿”。
    猜你喜欢
    • 2021-08-21
    • 2011-04-13
    • 2018-02-23
    • 2018-06-21
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 2021-02-09
    相关资源
    最近更新 更多