Remove org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder and fix deprecated Specification.where (#2760)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -11,7 +11,6 @@ package org.eclipse.hawkbit.repository.jpa;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
@@ -19,7 +18,6 @@ import lombok.AccessLevel;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity;
|
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity;
|
||||||
import org.eclipse.hawkbit.repository.jpa.repository.NoCountSliceRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.NoCountSliceRepository;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageImpl;
|
import org.springframework.data.domain.PageImpl;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@@ -36,15 +34,10 @@ import org.springframework.util.ObjectUtils;
|
|||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public final class JpaManagementHelper {
|
public final class JpaManagementHelper {
|
||||||
|
|
||||||
public static <T, J extends T> Optional<J> findOneBySpec(
|
|
||||||
final JpaSpecificationExecutor<J> repository, final List<Specification<J>> specList) {
|
|
||||||
return repository.findOne(combineWithAnd(specList));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, J extends T> Page<T> findAllWithCountBySpec(
|
public static <T, J extends T> Page<T> findAllWithCountBySpec(
|
||||||
final JpaSpecificationExecutor<J> repository, final List<Specification<J>> specList, final Pageable pageable) {
|
final JpaSpecificationExecutor<J> repository, final List<Specification<J>> specList, final Pageable pageable) {
|
||||||
if (CollectionUtils.isEmpty(specList)) {
|
if (CollectionUtils.isEmpty(specList)) {
|
||||||
return convertPage(repository.findAll(Specification.where(null), pageable), pageable);
|
return convertPage(repository.findAll(Specification.unrestricted(), pageable), pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertPage(repository.findAll(combineWithAnd(specList), pageable), pageable);
|
return convertPage(repository.findAll(combineWithAnd(specList), pageable), pageable);
|
||||||
@@ -56,9 +49,16 @@ public final class JpaManagementHelper {
|
|||||||
|
|
||||||
public static <J> Specification<J> combineWithAnd(final List<Specification<J>> specList) {
|
public static <J> Specification<J> combineWithAnd(final List<Specification<J>> specList) {
|
||||||
if (ObjectUtils.isEmpty(specList)) {
|
if (ObjectUtils.isEmpty(specList)) {
|
||||||
return Specification.where(null);
|
return Specification.unrestricted();
|
||||||
|
} else if (specList.size() == 1) {
|
||||||
|
return specList.get(0);
|
||||||
|
} else {
|
||||||
|
Specification<J> specs = specList.get(0);
|
||||||
|
for (final Specification<J> specification : specList.subList(1, specList.size())) {
|
||||||
|
specs = specs.and(specification);
|
||||||
|
}
|
||||||
|
return specs;
|
||||||
}
|
}
|
||||||
return specList.size() == 1 ? specList.get(0) : SpecificationsBuilder.combineWithAnd(specList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, J extends T> Slice<T> findAllWithoutCountBySpec(
|
public static <T, J extends T> Slice<T> findAllWithoutCountBySpec(
|
||||||
@@ -76,7 +76,7 @@ public final class JpaManagementHelper {
|
|||||||
|
|
||||||
public static <J> long countBySpec(final JpaSpecificationExecutor<J> repository, final List<Specification<J>> specList) {
|
public static <J> long countBySpec(final JpaSpecificationExecutor<J> repository, final List<Specification<J>> specList) {
|
||||||
if (CollectionUtils.isEmpty(specList)) {
|
if (CollectionUtils.isEmpty(specList)) {
|
||||||
return repository.count(Specification.where(null));
|
return repository.count(Specification.unrestricted());
|
||||||
}
|
}
|
||||||
|
|
||||||
return repository.count(combineWithAnd(specList));
|
return repository.count(combineWithAnd(specList));
|
||||||
@@ -92,16 +92,4 @@ public final class JpaManagementHelper {
|
|||||||
|
|
||||||
return repository.save(result);
|
return repository.save(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the format of filter string is 'name:version'. 'name' and 'version'
|
|
||||||
// fields follow the starts_with semantic, that changes to equal for 'name'
|
|
||||||
// field when the semicolon is present
|
|
||||||
public static String[] getFilterNameAndVersionEntries(final String filterString) {
|
|
||||||
final int semicolonIndex = filterString.indexOf(':');
|
|
||||||
|
|
||||||
final String filterName = semicolonIndex != -1 ? filterString.substring(0, semicolonIndex) : (filterString + "%");
|
|
||||||
final String filterVersion = semicolonIndex != -1 ? (filterString.substring(semicolonIndex + 1) + "%") : "%";
|
|
||||||
|
|
||||||
return new String[] { ObjectUtils.isEmpty(filterName) ? "%" : filterName, filterVersion };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,6 @@ import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.repository.TargetTagRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.TargetTagRepository;
|
||||||
import org.eclipse.hawkbit.repository.jpa.repository.TargetTypeRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.TargetTypeRepository;
|
||||||
import org.eclipse.hawkbit.repository.jpa.ql.QLSupport;
|
import org.eclipse.hawkbit.repository.jpa.ql.QLSupport;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
||||||
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
|
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
@@ -121,7 +120,7 @@ public class JpaTargetManagement
|
|||||||
TargetSpecifications.hasControllerId(controllerId));
|
TargetSpecifications.hasControllerId(controllerId));
|
||||||
|
|
||||||
final Specification<JpaTarget> combinedSpecification = Objects
|
final Specification<JpaTarget> combinedSpecification = Objects
|
||||||
.requireNonNull(SpecificationsBuilder.combineWithAnd(specList));
|
.requireNonNull(JpaManagementHelper.combineWithAnd(specList));
|
||||||
return jpaRepository.exists(AccessController.Operation.UPDATE, combinedSpecification);
|
return jpaRepository.exists(AccessController.Operation.UPDATE, combinedSpecification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.management;
|
package org.eclipse.hawkbit.repository.jpa.management;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -21,6 +20,7 @@ import org.eclipse.hawkbit.repository.QuotaManagement;
|
|||||||
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||||
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
|
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper;
|
||||||
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
||||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||||
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
|
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
|
||||||
@@ -31,7 +31,6 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
||||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionStatusRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.ActionStatusRepository;
|
||||||
import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
@@ -79,12 +78,11 @@ class OfflineDsAssignmentStrategy extends AbstractDsAssignmentStrategy {
|
|||||||
if (isMultiAssignmentsEnabled()) {
|
if (isMultiAssignmentsEnabled()) {
|
||||||
mapper = ids -> targetRepository.findAll(TargetSpecifications.hasControllerIdIn(ids));
|
mapper = ids -> targetRepository.findAll(TargetSpecifications.hasControllerIdIn(ids));
|
||||||
} else {
|
} else {
|
||||||
mapper = ids -> targetRepository.findAll(SpecificationsBuilder.combineWithAnd(
|
mapper = ids -> targetRepository.findAll(JpaManagementHelper.combineWithAnd(List.of(
|
||||||
Arrays.asList(TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, setId),
|
TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, setId),
|
||||||
TargetSpecifications.notEqualToTargetUpdateStatus(TargetUpdateStatus.PENDING))));
|
TargetSpecifications.notEqualToTargetUpdateStatus(TargetUpdateStatus.PENDING))));
|
||||||
}
|
}
|
||||||
return ListUtils.partition(controllerIDs, Constants.MAX_ENTRIES_IN_STATEMENT).stream().map(mapper)
|
return ListUtils.partition(controllerIDs, Constants.MAX_ENTRIES_IN_STATEMENT).stream().map(mapper).flatMap(List::stream).toList();
|
||||||
.flatMap(List::stream).toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetTypeSpecification;
|
import org.eclipse.hawkbit.repository.jpa.specifications.TargetTypeSpecification;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||||
@@ -27,7 +26,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
public interface TargetTypeRepository extends BaseEntityRepository<JpaTargetType> {
|
public interface TargetTypeRepository extends BaseEntityRepository<JpaTargetType> {
|
||||||
|
|
||||||
default List<JpaTargetType> findByDsType(@Param("id") final Long dsTypeId) {
|
default List<JpaTargetType> findByDsType(@Param("id") final Long dsTypeId) {
|
||||||
return findAll(Specification.where(TargetTypeSpecification.hasDsSetType(dsTypeId)));
|
return findAll(TargetTypeSpecification.hasDsSetType(dsTypeId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made
|
|
||||||
* available under the terms of the Eclipse Public License 2.0
|
|
||||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit.repository.jpa.specifications;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class to easily combine {@link Specification} instances.
|
|
||||||
*/
|
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
public final class SpecificationsBuilder {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combine all given specification with and. The first specification is the
|
|
||||||
* where clause.
|
|
||||||
*
|
|
||||||
* @param specList all specification which will combine
|
|
||||||
* @return <null> if the given specification list is empty
|
|
||||||
*/
|
|
||||||
public static <T> Specification<T> combineWithAnd(final List<Specification<T>> specList) {
|
|
||||||
if (specList.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Specification<T> specs = specList.get(0);
|
|
||||||
for (final Specification<T> specification : specList.subList(1, specList.size())) {
|
|
||||||
specs = specs.and(specification);
|
|
||||||
}
|
|
||||||
return specs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -56,6 +56,7 @@ import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetExcepti
|
|||||||
import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException;
|
import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException;
|
||||||
import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException;
|
import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException;
|
||||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction_;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaAction_;
|
||||||
@@ -65,7 +66,6 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification;
|
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.ActionStatusCreate;
|
import org.eclipse.hawkbit.repository.model.Action.ActionStatusCreate;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||||
@@ -1354,9 +1354,9 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
List<? extends DistributionSet> allFoundDS = distributionSetManagement.findAll(PAGE).getContent();
|
List<? extends DistributionSet> allFoundDS = distributionSetManagement.findAll(PAGE).getContent();
|
||||||
assertThat(allFoundDS).as("no ds should be founded").isEmpty();
|
assertThat(allFoundDS).as("no ds should be founded").isEmpty();
|
||||||
|
|
||||||
assertThat(distributionSetRepository.findAll(SpecificationsBuilder.combineWithAnd(Arrays
|
assertThat(distributionSetRepository.findAll(JpaManagementHelper.combineWithAnd(
|
||||||
.asList(DistributionSetSpecification.isDeleted(true), DistributionSetSpecification.isCompleted(true))),
|
List.of(DistributionSetSpecification.isDeleted(true), DistributionSetSpecification.isCompleted(true))), PAGE).getContent())
|
||||||
PAGE).getContent()).as("wrong size of founded ds").hasSize(noOfDistributionSets);
|
.as("wrong size of founded ds").hasSize(noOfDistributionSets);
|
||||||
|
|
||||||
IntStream.range(0, deploymentResult.getDistributionSets().size()).forEach(i -> testdataFactory.sendUpdateActionStatusToTargets(
|
IntStream.range(0, deploymentResult.getDistributionSets().size()).forEach(i -> testdataFactory.sendUpdateActionStatusToTargets(
|
||||||
deploymentResult.getDeployedTargets(), Status.FINISHED, Collections.singletonList("blabla alles gut")));
|
deploymentResult.getDeployedTargets(), Status.FINISHED, Collections.singletonList("blabla alles gut")));
|
||||||
@@ -1367,9 +1367,9 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// successfully and no activeAction is referring to created distribution sets
|
// successfully and no activeAction is referring to created distribution sets
|
||||||
allFoundDS = distributionSetManagement.findAll(pageRequest).getContent();
|
allFoundDS = distributionSetManagement.findAll(pageRequest).getContent();
|
||||||
assertThat(allFoundDS).as("no ds should be founded").isEmpty();
|
assertThat(allFoundDS).as("no ds should be founded").isEmpty();
|
||||||
assertThat(distributionSetRepository.findAll(SpecificationsBuilder.combineWithAnd(Arrays
|
assertThat(distributionSetRepository.findAll(JpaManagementHelper.combineWithAnd(
|
||||||
.asList(DistributionSetSpecification.isDeleted(true), DistributionSetSpecification.isCompleted(true))),
|
List.of(DistributionSetSpecification.isDeleted(true), DistributionSetSpecification.isCompleted(true))), PAGE).getContent())
|
||||||
PAGE).getContent()).as("wrong size of founded ds").hasSize(noOfDistributionSets);
|
.as("wrong size of founded ds").hasSize(noOfDistributionSets);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made
|
|
||||||
* available under the terms of the Eclipse Public License 2.0
|
|
||||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit.repository.jpa.specifications;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
|
||||||
import jakarta.persistence.criteria.CriteriaQuery;
|
|
||||||
import jakarta.persistence.criteria.Expression;
|
|
||||||
import jakarta.persistence.criteria.Path;
|
|
||||||
import jakarta.persistence.criteria.Predicate;
|
|
||||||
import jakarta.persistence.criteria.Root;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Feature: Unit Tests - Repository<br/>
|
|
||||||
* Story: Specifications builder
|
|
||||||
*/
|
|
||||||
class SpecificationsBuilderTest {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the combination of specs on an empty list which returns null
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
void combineWithAndEmptyList() {
|
|
||||||
final List<Specification<Object>> specList = Collections.emptyList();
|
|
||||||
assertThat(SpecificationsBuilder.combineWithAnd(specList)).isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the combination of specs on an immutable list with one entry
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
void combineWithAndSingleImmutableList() {
|
|
||||||
final Specification<Object> spec = (root, query, cb) -> cb.equal(root.get("field1"), "testValue");
|
|
||||||
final List<Specification<Object>> specList = Collections.singletonList(spec);
|
|
||||||
final Specification<Object> specifications = SpecificationsBuilder.combineWithAnd(specList);
|
|
||||||
assertThat(specifications).as("Specifications").isNotNull();
|
|
||||||
|
|
||||||
// mocks to call toPredicate on specifications
|
|
||||||
final CriteriaBuilder criteriaBuilder = mock(CriteriaBuilder.class);
|
|
||||||
final Path field1 = mock(Path.class);
|
|
||||||
final Predicate equalPredicate = mock(Predicate.class);
|
|
||||||
final CriteriaQuery<Object[]> query = mock(CriteriaQuery.class);
|
|
||||||
final Root<Object> root = mock(Root.class);
|
|
||||||
|
|
||||||
when(criteriaBuilder.equal(any(Expression.class), anyString())).thenReturn(equalPredicate);
|
|
||||||
when(root.get("field1")).thenReturn(field1);
|
|
||||||
|
|
||||||
final Predicate predicate = specifications.toPredicate(root, query, criteriaBuilder);
|
|
||||||
|
|
||||||
assertThat(predicate).isEqualTo(equalPredicate);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the combination of specs on a list with multiple entries
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
void combineWithAndList() {
|
|
||||||
final Specification<Object> spec1 = (root, query, cb) -> cb.equal(root.get("field1"), "testValue1");
|
|
||||||
final Specification<Object> spec2 = (root, query, cb) -> cb.equal(root.get("field2"), "testValue2");
|
|
||||||
|
|
||||||
final List<Specification<Object>> specList = new ArrayList<>(2);
|
|
||||||
specList.add(spec1);
|
|
||||||
specList.add(spec2);
|
|
||||||
|
|
||||||
final Specification<Object> specifications = SpecificationsBuilder.combineWithAnd(specList);
|
|
||||||
assertThat(specifications).as("Specifications").isNotNull();
|
|
||||||
|
|
||||||
// mocks to call toPredicate on specifications
|
|
||||||
final CriteriaBuilder criteriaBuilder = mock(CriteriaBuilder.class);
|
|
||||||
final Path field1 = mock(Path.class);
|
|
||||||
final Path field2 = mock(Path.class);
|
|
||||||
final Predicate equalPredicate1 = mock(Predicate.class);
|
|
||||||
final Predicate equalPredicate2 = mock(Predicate.class);
|
|
||||||
final Predicate combinedPredicate = mock(Predicate.class);
|
|
||||||
final CriteriaQuery<Object[]> query = mock(CriteriaQuery.class);
|
|
||||||
final Root<Object> root = mock(Root.class);
|
|
||||||
|
|
||||||
when(criteriaBuilder.equal(any(Path.class), eq("testValue1"))).thenReturn(equalPredicate1);
|
|
||||||
when(criteriaBuilder.equal(any(Path.class), eq("testValue2"))).thenReturn(equalPredicate2);
|
|
||||||
when(criteriaBuilder.and(equalPredicate1, equalPredicate2)).thenReturn(combinedPredicate);
|
|
||||||
when(root.get("field1")).thenReturn(field1);
|
|
||||||
when(root.get("field2")).thenReturn(field2);
|
|
||||||
|
|
||||||
final Predicate predicate = specifications.toPredicate(root, query, criteriaBuilder);
|
|
||||||
|
|
||||||
assertThat(predicate).as("Combined predicate").isEqualTo(combinedPredicate);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user