Я создаю хранилище данных с помощью Spring Boot и Angular. Для некоторых таблиц мне нужна комбинация поиска, фильтрации, (мульти) сортировки и просмотра страниц. Поэтому я использую Querydsl, он идеально соответствует моим потребностям. Но у меня есть некоторые проблемы с этим. После создания приложения Java сортировка иногда не работает для некоторых атрибутов моего объекта. Отладка показала, что параметр sorting
в pageable
равен UNSORTED
для этих указанных атрибутов.
Чтобы сделать это более понятным, я покажу некоторый код. Объект:
Entity
@Table(name = "ExternalEffortLinkManagement", schema = "dbo")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "externalEffortLinkManagementId")
public class ExternalEffortLinkManagement {
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
@Column(name = "ExternalEffortLinkManagement_ID")
private long externalEffortLinkManagementId;
@Column(name = "Mitarbeiter")
private String employee;
@Column(name = "Jahr")
private int year;
@Column(name = "Monat")
private int month;
@Column(name = "Projektnummer")
private String projectNumber;
@Column(name = "InitialMailSent")
private Timestamp initialMailSent;
@Column(name = "LastReminderSent")
private Timestamp lastReminderSent;
@Column(name = "Active")
private boolean active;
Метод в контроллере:
@RequestMapping(value = EXTERNAL_EFFORT_LINK_MANAGEMENT_URL + "/advancedSearch", method = RequestMethod.GET)
@ResponseBody
public PagedResources<ExternalEffortLinkManagement> advancedSearch(
@RequestParam(value = "search", required = false) String search,
Pageable pageable, @RequestParam MultiValueMap<String, String> parameters,
PersistentEntityResourceAssembler persistentEntityResourceAssembler
) {
SimpleGrantedAuthority[] allowedRoles = {SYSADMIN, SUBCONTRACTOR_MANAGEMENT}; // <-- Debug point was here
GeneralPredicateBuilder<ExternalEffortLinkManagement> builder = new GeneralPredicateBuilder<ExternalEffortLinkManagement>(ExternalEffortLinkManagement.class);
Predicate predicate = predicateService.getPredicateFromParameters(parameters, ExternalEffortLinkManagement.class);
Page<ExternalEffortLinkManagement> results = service.advancedSearch(
this.buildAdvancedSearch(search, predicate, builder), pageable, allowedRoles);
return super.toPagedResource(results, persistentEntityResourceAssembler);
}
Репозиторий:
@CrossOrigin(exposedHeaders="Access-Control-Allow-Origin")
@RepositoryRestResource(collectionResourceRel = EXTERNAL_EFFORT_LINK_MANAGEMENT_URL, path = EXTERNAL_EFFORT_LINK_MANAGEMENT_URL)
public interface ExternalEffortLinkManagementRepositoryExtEff extends PagingAndSortingRepository<ExternalEffortLinkManagement, Long>, JpaSpecificationExecutor<ExternalEffortLinkManagement>, QuerydslPredicateExecutor<ExternalEffortLinkManagement> {
};
Метод обслуживания:
public Page<ExternalEffortLinkManagement> advancedSearch(Predicate predicate, Pageable pageable, SimpleGrantedAuthority[] roles){
if (SecurityUtils.userHasAnyRole(roles)) {
return this.calcSumHours(this.repository.findAll(predicate, pageable));
} else throw new ForbiddenException(FORBIDDEN);
}
Теперь, когда вы увидели код, позвольте мне четко объяснить поведение.
Сначала я запускаю gradle clean
, затем gradle build
и затем приложение. После этого я делаю запрос (не имеет значения, делаю ли я это из приложения или прямо в браузере или в Postman et c., Результат тот же) advancedSearch?page=0&size=10&sort=employee,asc&sort=active,asc&month=1&year=2020
. Все отлично, результаты сначала сортируются по employee
, а затем по active
.
Теперь я останавливаю приложение, gradle build
, запускаю приложение. При повторном выполнении запроса employee
игнорируется при сортировке, результаты сортируются только по флажку active
.
Теперь я снова останавливаю приложение, gradle build
, запускаю приложение. Делая запрос снова, все работает. Я не бегал clean
! И я ничего не изменил в исходном коде.
Теперь, опять в четвертый раз, я останавливаю приложение, gradle build
, запускаю приложение. При повторном выполнении запроса employee
игнорируется при сортировке, результаты сортируются только по флажку active
. После четвертой сборки я больше не работаю, пока не введу команду clean
.
Чтобы сделать его более сложным, чем он есть, поведение аналогично для некоторых из атрибуты объекта. Не имеет значения, комбинирую ли я параметры сортировки или просто использую их.
employee
: иногда работает projectNumber
: иногда работает initialMailSent
, lastReminderSent
, active
: работает всегда (также в
Когда сотрудник не working
, projectNumber
также не работает, с другой стороны, если один работает, другой также работает.
Фильтры (month
, year
) всегда одинаковы и не влияют на поведение.
Querdsl генерирует некоторые классы, поэтому я подумал, что эти классы могут вызвать проблему. Но это не так, потому что у меня почти такая же проблема в цепочке непрерывной интеграции, там происходит переключение между работой в первой сборке, не работой во второй, работой в третьей и так далее. Так что просто шаги 2 и 3. В цепочке сборка всегда начинается с чистого кода (без сгенерированных классов, они были сгенерированы во время сборки).
У кого-нибудь есть такая же проблема и лучшее объяснение и решение?