How to update the content inside of Page object from Spring Data without changing the other properties - spring-boot

after querying from the database using the given getAll(Pageable pageable) method from spring data jpa i become an Page object. What I am doing is modifing the content list inside of this Page object but I am getting stuck here is that I dont know how to set it back to the Page object because Page doesn't have setter method, something like page.setContent(newContent), it has only getter.
Can anyone give me some hints how to set the new content to the Page object without changing the other current properties inside of it?

You need to use PageImpl(List content, Pageable pageable, long total) as example below :
//get paged data
Page<Groups> groups = groupsRepository.
findPagedGroups(pageable, lowerCase(name), lowerCase(description));
// update list
List<Groups> groupsList = groups.stream().collect(Collectors.toList());
for (Groups group : groupsList) {
group.setSize(usersGroupsRepository.countActiveUsersGroupsForGroupId(group.getId()));
}
// return new PageImpl
return new PageImpl<>(groupsList, pageable, groups.getTotalElements());

Related

Entity being tracked despite AsNoTracking

I have an object, Client, with a navigation property that is a list of Order objects. Whenever I retrieve a Client object, I include the list of Orders, with AsNoTracking().
public new IQueryable<Client> FindByConditionNoTracking(Expression<Func<Client, bool>> expression)
{
return this.ClientContext.Set<Client>().Include(s => s.Orders)
.Where(expression).AsNoTracking();
}
In my UpdateClient repository method, I take in a Client object. I then attempt to retrieve that original client from the database (using Include to get the child Orders), map the Client param to the original, and save to the database. Over here, I do not use AsNoTracking, because I specifically want the changes to be tracked.
public new void Update(Client client)
{
var id = client.ClientId;
var original = this.ClientContext.Clients.Include(s => s.Orders).Where(s => s.ClientId == id)
.FirstOrDefault<Client>();
original = _mapper.Map(client, original);
this.ClientContext.Update(original);
}
The error I am getting is that an instance of Order with the same key value is already being tracked. A few problems with that:
Wherever the Client and the child Orders are retrieved for the purposes of display I use AsNoTracking.
The only place where I retrieve without AsNoTracking is where I get the original within this very method.
The bug isn't with the parent property. If I was improperly retrieving the Client elsewhere, wouldn't I have this error with the Client id itself? But the error seems to be only with the navigation property.
All insight is appreciated!
If anyone else runs into this: Automapper, when mapping collections, apparently recreates the entire collection. I solved the above issue by using Automapper.Collections in my mapping configuration. Thanks to Mat J for the tip!

Change page size of Pageable(spring boot jpa)

I´m working showing some info on a table and I´m using #PageableDefault(size = Constants.PAGE_SIZE) Pageable pageable to determine the size of the page im showing(5 elements at the moment).
The point here is that I want to be able to change the value of that page size using a <select> to be able to modify the page size in my controller and redirect it into my table endpoint:
#PostMapping("/size")
public String size(){
//Constants.PAGE_SIZE;
return "redirect:/users/showusers";
}
Any help will be appreciated.
You can pass page request like this, pass your size variable in page request.
PageRequest pageRequest = PageRequest.of(0, 5); //or default
use below to pass page size dynamically..
PageRequest pageRequest = PageRequest.of(0, size);
in repository method pass Pageable pageable

how to pass value dynamically to spring top function

Actually, I wanted to retrieve the Top 500 records in a table. I knew spring data has internal method findTop500 method for it. My question is can this 500 be passed dynamically? Suppose if my requirement changes to get Top1000 I don't want it to modify again.
Assuming you are asking about Spring data-methods
You can use a Pageable object to dynamically set how many entries you want to retrieve.
You can use it like this:
PageRequest pageRequest = new PageRequest(0, maxResults);
List<Record> records = repository.findAll(pageRequest);
List<Record> records = repository.findAllByKey(key, pageRequest);

Spring boot + JPA(Hibernate) Edit partial entity fields

all.
I have following simple form in which I want to edit the entity. The problem is that I have some fields which I don't want to be edited. For example (Image file path).
As it is now, I have the service method -
public void addOrModifyLayout(Layout layout){
if(layout.getId() == null){
layoutRepository.save(layout);
}
else {
Layout modifiedLayout = new Layout();
modifiedLayout.setId(layout.getId());
modifiedLayout.setName(layout.getName());
modifiedLayout.setStatus(layout.getStatus());
modifiedLayout.setExhibitor(layout.getExhibitor());
layoutRepository.save(modifiedLayout);
}
}
As you can see, every field that I want to be able to be edited, I should explicitly put it in the service. Can I use some mapper or trick to update only some fields that are in the view (form) ? How you handle this kind of issues?
You can either
store all the entity fields in hidden inputs (e.g. imageFilePath hidden input). So you can store on UI all the entity fields and get them back to assign to the entity.
OR
Avoid new entity creation but retrieve existing one and fill only necessary fields.
Layout modifiedLayout = layoutRepository.getById(layout.getId());
modifiedLayout.setName(layout.getName());
modifiedLayout.setStatus(layout.getStatus());
modifiedLayout.setExhibitor(layout.getExhibitor());
layoutRepository.save(modifiedLayout);

Spring dynamically select #JsonView with pagination

I want to select the Json View applied to my data depending on an URL parameter. I am trying to implement this using #JsonView annotations, and I tried some solutions (1, 2). The thing is that those solutions are basen on the controller action returning a MappingJacksonValue, but I cannot use that because I am using pagination.
My action:
public ResponseEntity<Page<MyEntity>> findAll(
int viewMode,
Pageable pageable) {
result = service.findAll(pageable);
// Here I would like to apply a Json View to the result set depending
// on the variable viewMode
return new ResponseEntity<Page<MyEntity>>(
/* Resultset with the selected view applied, and paginated */,
HttpStatus.OK
);
}
To make #JsonView work with pagination, you need to set the following property to true in application.properties:
spring.jackson.mapper.DEFAULT_VIEW_INCLUSION = true
This will cause the mapper to also serialize properties which are not annotated, enabling paging to work.

Resources