JPQL 中的方向性加入 Spring Boot JPA?

Directionality in JPQL joins for Spring Boot JPA?

Spring 在这里开机。我有以下两个 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 实现:

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

基本上,给我所有 "orphaned" 并且与这里的任何帐户相关联的配置文件。

我对我是否需要 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();
}

谁能帮我填补空白?

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

其次,如果您想检查孤立记录,您绝对不想加入table他们孤立的记录。

你最后一次尝试,

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();
}

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

FROM Profile p WHERE p.accounts IS EMPTY