如果用户在page
参数中提供排序列,我有以下存储库方法,完全符合我的需要:
public interface IdentityRepository extends JpaRepository<Identity, String> {
@Query("select distinct ident from Identity ident left outer join ident.authorities authority "
+ "where ("
+ "(:src is null or ident.source = :src) and "
+ "(:org is null or ident.organization = :org) and "
+ "(:auth is null or authority.authority = :auth) and "
+ "(:authSrc is null or authority.authoritySource = :authSrc))")
@RestResource(path="filter")
public Page<Identity> findWithFilter(
@Param("src") String source,
@Param("org") String org,
@Param("auth") Authority auth,
@Param("authSrc") AuthoritySource authSrc,
Pageable page);
...
}
如果调用者提供了页数而不是排序列,则在检索所有页面时,他们将返回正确的号结果。但是,许多实体将被复制,因此即使结果计数正确,也会丢失许多预期实体,而其他实体则重复(或重复)。
我想知道的是,如果用户没有指定默认排序列和方向,是否有办法提供。我已经知道@EnableSpringDataWebSupport
可以在这里提供帮助,但是我们没有使用Spring MVC,所以我没有任何控制器来附加@SortDefaults
。我们正在使用Spring Data Rest。此外,我已尝试将方法名称更改为findWithFilterOrderByIdAsc
,但这似乎没有帮助。在Spring JIRA中跨过this issue,我相信这正是我所需要的,但在它解决之前,有没有人知道一个解决方法?
这是我的实体......
@Entity
@Table(name = "identity", indexes = { @Index(columnList = "user_id", unique = true) })
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Audited
public class Identity implements Serializable, Identifiable<String> {
/**
* The unique identifier for this identity within the IDD application.
*/
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "IDDUidGenerator")
@GenericGenerator(name = "IDDUidGenerator")
private String id;
/**
* The name of the identity provider wherein this identity is originally defined.
*/
@Column(name = "source")
private String source = INTERNAL_SOURCE;
/**
* The unique identifier for this identity within the customer's identity provider.
*/
@NotNull
@Column(name = "user_id", nullable = false, unique = true)
private String userId;
/**
* The roles this identity is authorized to perform.
*/
@OneToMany(fetch = FetchType.EAGER, mappedBy = "identity", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<IdentityAuthority> authorities = new HashSet<>();
...
}
及其子实体......
@Entity
@Table(name = "identity_authority")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Audited
public class IdentityAuthority implements Serializable, Identifiable<Long> {
private static final long serialVersionUID = -5315412946768343445L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@XmlTransient
@JsonIgnore
private Long id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "identity_id", nullable = false)
@XmlTransient
@JsonIgnore
private Identity identity;
@Enumerated(EnumType.STRING)
@Column(name = "authority", length = 20, nullable = false)
private Authority authority;
@Enumerated(EnumType.STRING)
@Column(name = "authority_source", length = 30, nullable = false)
private AuthoritySource authoritySource;
...
}
这是我为证明问题而运行的测试案例......
@Test
public void testPagedRequestsReturnAllResults() {
// Create identities
String source = "One Hundred Identities Generator";
int numIdentities = 100;
int pageSize = 5;
List<Identity> input = new ArrayList<>();
for (int i=0; i<numIdentities; i++) {
Identity identity = new Identity();
identity.setUserId(UUID.randomUUID().toString());
identity.setSource(source);
input.add(identity);
}
// Save identities
List<Identity> output = repository.saveBulk(input);
Set<String> savedIds = collectIds(output, null);
assertThat(savedIds.size()).isEqualTo(numIdentities);
// Test Sorted Find Filter with Paging (THIS PASSES)
Pageable pageRequest = new PageRequest(0, pageSize, new Sort(Direction.ASC, "id"));
Set<String> foundPagedIds = new HashSet<>();
do {
Page<Identity> page = repository.findOrderByIdAsc(source, null, null, null, pageRequest);
List<Identity> foundIdentities = page.getContent();
foundPagedIds = collectIds(foundIdentities, foundPagedIds);
pageRequest = page.nextPageable();
} while (pageRequest != null);
assertThat(foundPagedIds.size()).isEqualTo(numIdentities);
assertThat(foundPagedIds).isEqualTo(savedIds);
// Test Unsorted Find Filter with Paging (THIS FAILS)
pageRequest = new PageRequest(0, pageSize);
foundPagedIds = new HashSet<>();
do {
Page<Identity> page = repository.findOrderByIdAsc(source, null, null, null, pageRequest);
List<Identity> foundIdentities = page.getContent();
foundPagedIds = collectIds(foundIdentities, foundPagedIds);
pageRequest = page.nextPageable();
} while (pageRequest != null);
assertThat(foundPagedIds.size()).isEqualTo(numIdentities);
assertThat(foundPagedIds).isEqualTo(savedIds);
}