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
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