How to Use sorting in Spring Data Rest GET method - spring

When I create any repository in spring framework like following it gives method by default to get all records of the entity using this API
GET : http://localhost:3000/api/addresses
It sends data from ascending order But If I want my data in descending order than How can I specify this ?
Address Repository
public interface AddressRepository extends JpaRepository<Address, Long>
{
}

Perhaps,you can :
localhost:3000/api/addresses?sort={property},desc
this will help you sort by property desc

You can also specify this as part of your request, take a look at documentation here Sorting.
Also please take a look at similar answer here.

Try inside the AddressRepository class something like:
public List<Address> findAllByOrderByIdDesc();
of course you can change the "ById" part with any other field you want to use for sorting.

Related

Spring reactive without using Entity class

I need to expose reactive end-points i.e Flux/Mono in Spring+Java. But I
don't want to use Entity class as the definition of Entity class may keep on changing
and we can have dynamic need to register new Entity classes.
Is there any way we can implement Spring Reactive end-points without Entity class.
I am using Spring+Java and Mongodb.
The Spring framework relies on entities, whether reactive or not. It basically doesn’t affect you because you need to have knowledge of the document to reference a key value. What is not in the entity will not be set for it. If the element does not exist but the entity does, NULL is set.
If you use Kotliin, I recommend using nullable values like the "?" symbol if not guaranteed to non-null.
Side note: How would you like to do anything if you don't know what you're storing?
I got a solution that as follows:
You can use ReactiveMongoTemplate. For example:
#Autowired
private ReactiveMongoTemplate mongoTemplate;
public Flux<Document> findAll() {
return mongoTemplate.findAll(Document.class,"employee");
}
public Mono<Document> save(Document data){
return mongoTemplate.save(data,"employee");
}
So Instead of passing any Entity Class, you can use Document.class

Spring data JPA Checkmarx vulnerability- Improper Resource Access Authorization for #Query annotation

We are currently working on web application with persistence layer implemented using Spring data JPA and its working out really well for us however while scanning our code using checkmarx it complains for "Improper Resource Access Authorization" error for all input parameter in below code snippet.Not sure how to resolve it.Based of my understanding we tried following approach but that didn't help either
Whitelist input parameter using using #valid and #Pattern
annotations
Secure method using #Secured("ROLE_TEST") annotation of spring security.
#Repository
public interface EmployeeAddressRepository extends JpaRepository<EmployeeAddress, Integer> {
#Query("select empAdd from EmployeeAddress empAdd where empAdd.Employee.employeeId=?1 and (endDate) ORDER BY empAdd.lastUpdateTimeStamp DESC")
List<EmployeeAddress> findEmployeeAddressByEmployeeId(String employeeId, LocalDate date) throws PersistenceException;
}
Looking forward for any pointer here to move forward in right direction
In the comments for one of the other answers someone provided the answer. Essentially Checkmarx is unable to determine if you are checking if the user/service has permission to execute this command.
A secure implementation would look like:
if(userCanPerformAction(employeeId)){
repository.findEmployeeAddressByEmployeeId(employeeId, date)
}
It's not smart enough to know if your code prior to the call to the repository has actually performed the checks needed. So, what you have to do is verify that you are doing the correct validation checks before executing findEmployeeAddressByEmployeeId. If you are, then you would follow your organizations process for marking something as a false positive.
Perhaps Checkmarx doesn't support ordinal parameters notation, try rewriting the query like so:
#Query("select empAdd from EmployeeAddress empAdd where empAdd.Employee.employeeId= :empId and (endDate) ORDER BY empAdd.lastUpdateTimeStamp DESC", employeeIdParameter)
where employeeIdParameter is the input parameter.
Hope this helps,
Amit

Spring - RESTful provide different entity representations

In advance, I'm not speaking of Content Negotiation. Let's assume I've a simple JPA entity, by the way it is convertible with a related DTO it doesn't matter.
#Entity
public class User {
...
private String email;
private String password;
...
}
I've a RESTful controller with two different routes, a secured one and a public one.
#RestController
public class UserController {
...
#GetMapping("/public")
private User publicRoute() {
return service.getLatestUser();
}
#Secured("...")
#GetMapping("/private")
private User privateRoute() {
return service.getLatestUser();
}
}
For both routes the same entity is returned, but in the first case a public representation, let's say for a user profile, without sensitive stuff like E-Mail and Password should be returned. However in the second case a private representation, let's say for the owner itself, is required.
Is there any elegant way for doing this? I tried it on JSON level with #JsonIgnore but it doesn't worked for me. Also I tried to use Response-Objects, but it results in a lot of boilerplate code! Any suggestions?
See Also:
Recommended by Ananthapadmanabhan there already exists some questions/resources about this topic:
Spring REST webservice serializing to multiple JSON formats
How do I serialize using two different getters based on JsonView in RestController?
You could have different DTO objects being returned from the two endpoints instead of returning the same Entity class, that way you can have control over which attributes should be there in the response.
Read here about the advantages of using a DTO .
Another approach that you could make is to have custom serializers and deserializers for your endpoint.
You could read here for more details.
And here
Ignore dto fields while sending back to controller.
you can write you own method if your object is not final
private User ignoreEmailAndPass(User user){User usr=new User();usr.setName();//send only required fields.}
from Question:
In the database table you can have two roles
Say like User and Owner
3.In the service,check if it is user or owner and get the required details then have the
two DTOs,for each of their information that you want to send,set the info and return.
Or have a Common DTO, conataining all the information and when want to send user info just ignore the other info{Subset} else all.
Tell me what do you think of this solution?

Spring Data MongoDB: Specifying a hint on a Spring Data Repository find method

I am implementing a Spring Data Repository and having my repository extend the MongoRepository. I am looking for a way to specify a hint on my findBy methods so I can be control. I have seen several times when a non-optimal index would be picked as the winning plan.
This is what my repository looks like right now:
public interface AccountRepository extends MongoRepository<Account, ObjectId> {
#Meta(maxExcecutionTime = 60000L, comment = "Comment" )
public List<Account> findByUserIdAndBrandId(Long userId, Long brandId);
}
I researched a bunch and found that the JPARepository from spring data supports the #QueryHint annotation but I do not believe that annotation is supported for MongoDb. Is there a similar annotation I can specify on top of my findBy method to specify the hint?
MongoTemplate allows to specify a hint, however, I have a ton of findBy methods and I would hate to add an implementation underneath just to specify a hint.

Limit findAll possible with Spring?

Is it possible with Springs auto implemented repositories to limit the result size of the findAll method?
I'm trying to have something like the following declared in the interface:
List<XY> findAllTopTen();
Unfortunatelly, it doesn't work (this) way...
If you dont have a Pageable object that came from your controller and just need to get X amount of objects from DB, you can do the following:
First, your Repository class has to extend JpaRepository<T, ID> so it wil be able to query using a Pageable object.
Second, you can define a Pageable object this way:
Pageable limit = PageRequest.of(0,10);
return repository.findall(limit);
In this case, the query would return the first 10 objects.
You can find more info here (Scroll down to 4.1, Example 4)
Note that the example actually extends PagingAndSortingRepository but JpaRepository contains all the methods from PagingAndSortingRepository and has additional functions aswell.
Edit: Thanks to #Zunnii for pointing out that new PageRequest() is now deprecated. I edited the snippet above to reflect that.
Pass a Pageable as a parameter like following:
Page<x> findAll(Pageable pageable);
You need to explicitly specify the ordering, otherwise Spring Data JPA has no way of deciding what criteria it should use. For instance:
List<XY> findAllTopTenByAge();
See more details in the official documentation.

Resources