Spring Data的PagingAndSortingRepository是否支持带EmbeddedId的复合主键JPA实体?
关于Spring Data JPA中PagingAndSortingRepository支持@EmbeddedId复合主键的解答
嘿,好问题!刚好我对这块比较熟悉,直接给你明确结论:Spring Data JPA的PagingAndSortingRepository(包括继承它的JpaRepository)是原生支持使用@EmbeddedId实现复合主键的实体的,完全不需要手动实现核心的分页、排序逻辑,这属于Spring Data的内置能力。
下面给你拆解下具体怎么用:
1. 正确配置实体类和复合主键
首先你需要定义一个标记为@Embeddable的复合主键类,然后在实体中用@EmbeddedId来引用它:
// 复合主键类 @Embeddable public class OrderItemId implements Serializable { private Long orderId; private Long productId; // JPA要求必须提供无参构造器,同时要实现equals和hashCode方法 public OrderItemId() {} public OrderItemId(Long orderId, Long productId) { this.orderId = orderId; this.productId = productId; } // 省略getter、setter、equals、hashCode方法 } // 实体类 @Entity public class OrderItem { @EmbeddedId private OrderItemId id; private Integer quantity; private BigDecimal price; // 省略构造器、getter、setter方法 }
2. 定义仓库接口
直接继承JpaRepository或者PagingAndSortingRepository就行,泛型参数传入实体类和复合主键类:
public interface OrderItemRepository extends JpaRepository<OrderItem, OrderItemId> { // 还可以添加自定义的分页查询方法 Page<OrderItem> findByIdOrderId(Long orderId, Pageable pageable); }
3. 分页排序的使用示例
在业务代码里,你可以直接调用仓库的分页方法,排序时需要指定复合主键里的属性(注意要通过@EmbeddedId字段名来导航):
// 构造分页请求:第0页,每页10条,按订单ID降序排序 Pageable pageable = PageRequest.of(0, 10, Sort.by("id.orderId").descending()); Page<OrderItem> orderItemPage = orderItemRepository.findAll(pageable); // 或者调用自定义的分页查询,筛选特定订单下的商品 Page<OrderItem> specificOrderItems = orderItemRepository.findByIdOrderId(1001L, pageable);
补充说明
你提到已知可以手动实现该接口,其实完全没必要这么做——Spring Data已经帮你封装好了所有分页、排序的核心逻辑,只要你的实体和仓库接口配置正确,就能直接使用这些能力。唯一需要注意的是,复合主键类必须实现Serializable接口,并且提供正确的equals和hashCode方法,这是JPA对复合主键的硬性要求。
内容的提问来源于stack exchange,提问作者David I.
相关产品推荐
相关产品推荐

