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 过滤:
select u from UserActivity u, Customer c where u.user.id = c.id
select u from UserActivity u where u.user.id in (select id from Customer)
选择你更喜欢的任何一个,因为现代数据库中的优化器会优化这两种查询,以便两种情况下的性能相同。
考虑这个 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 过滤:
select u from UserActivity u, Customer c where u.user.id = c.id
select u from UserActivity u where u.user.id in (select id from Customer)
选择你更喜欢的任何一个,因为现代数据库中的优化器会优化这两种查询,以便两种情况下的性能相同。