Closed samie820 closed 4 years ago
Yes, it's possible. See the following example.
@Entity
public class Order {
private String status;
private String name;
private String surname;
@ManyToOne
@JoinColumn
private User user;
}
@Conjunction(
value = {
@Or({
@Spec(path = "name", params = "q", spec = LikeIgnoreCase.class),
@Spec(path = "surname", params = "q", spec = LikeIgnoreCase.class)
})
},
and = {
@Spec(path = "status", params = "status", spec = Equal.class)
}
)
public interface OrderSpec extends Specification<Order> {
}
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.Predicate;
import java.util.*;
public class SpecBuilder {
public static <T> Specification<T> joinUser(final Specification<T> spec) {
return (Specification<T>) (root, query, cb) -> {
List<Predicate> predicateList = new ArrayList<>();
if (spec != null) {
predicateList.add(spec.toPredicate(root, query, cb));
}
predicateList.add(cb.equal(root.get("user").get("username"), SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString()));
return cb.and(predicateList.stream().filter(Objects::nonNull).toArray(Predicate[]::new));
};
}
}
@RestController
@RequestMapping("/orders")
public class OrderController {
private final OrderRepository repository;
@GetMapping
public ResponseEntity find(OrderSpec spec) {
Page<Order> page = repository.findAll(SpecBuilder.joinUser(spec));
return ResponseEntity.ok(page);
}
}
First convert current specification to Predicate object, then combine with new one (just like in SpecBuilder).
Oh wow...thanks a lot, I ended up making a custom implementation that looks something like that, thanks again
I'm glad to hear that.
Don't forget to close the issue :D
Please, is it possible to add an extended Specification. For example: