Spring 数据 JPA 以在查询中加入子类

Spring data JPA to join subclasses in query

考虑这个 class:

@Entity
@Table(name = "USER_TABLE")
@Inheritance(strategy = InheritanceType.JOINED)
public class User {

    @Id
    @GenericGenerator(name = "system-uuid", strategy = "uuid2")
    @GeneratedValue(generator="system-uuid")
    @Column(name = "id", unique = true)
    @Type(type= "org.hibernate.type.PostgresUUIDType")
    private UUID id;

    @Column(name = "USERNAME")
    private String userName;
}

及其简单 child:

@Entity
@Table(name = "CUSTOMER")
public class Customer extends User{
        //some extra fields
}

我还有另一个 class 与用户有关:

@Entity
@Table(name = "USER_ACTIVITY")
public class UserActivity {

    @ManyToOne
    @JoinColumn(name = "USERID")
    private User user;

    //id and other fields
}

这是棘手的部分。我想获取与 "Customer" 相关的所有 objects 类型的 UserActivity。我试过这样的事情:

public interface UserActivityRepository extends PagingAndSortingRepository<UserActivity,UUID> {
    @Query("select u from UserActivity u join Customer.id")
    List<UserActivity> findAllByUserIsNotNullOrderByCreatedDesc(Pageable pageable);
}

但是 hibernate 告诉我指定了一个无效路径。

你能帮我解决这个问题吗?

在您的 User 实体中使用 @DiscriminatorColumn(name = "TYPE")

@Entity
@Table(name = "USER_TABLE")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "TYPE")
@DiscriminatorValue("USER")
public class User {

    ...

}

在您的 Customer 实体中定义一个 @DiscriminatorValue("CUSTOMER")

@Entity
@Table(name = "CUSTOMER")
@DiscriminatorValue("CUSTOMER")
public class Customer extends User {

    ...

}

像这样查询您的存储库

@Query("select u from UserActivity u join u.user user where TYPE(user) = 'CUSTOMER'")
List<UserActivity> findAllByUserIsNotNullOrderByCreatedDesc();

注意: @DiscriminatorValue注释不是强制的。 JPA 根据实体类型推断列名。

您可以明确加入 Customer 或按属于 Customer 个 ID 的 User 个 ID 过滤:

  1. select u from UserActivity u, Customer c where u.user.id = c.id
  2. select u from UserActivity u where u.user.id in (select id from Customer)

选择你更喜欢的任何一个,因为现代数据库中的优化器会优化这两种查询,以便两种情况下的性能相同。