Home > Back-end >  Class sorting JSON by ID instead of highest value
Class sorting JSON by ID instead of highest value

Time:03-19

I'm doing a vote counting system, the winner is the one who has more than 3 votes, however, I'm facing the following problem. When there is more than one place with 3 votes, instead of my JSON returning the one with the most votes, it always returns the one with more than 3 votes ordered by ID. That is, if the restaurant with ID 1 has 3 votes, and the restaurant with ID 2 has 10 votes, the restaurant with ID 1 ends up appearing on the route /restaurants/winner despite not being the most voted, is there any way I can make the most voted show up?

e.g: return from /restaurants/winner route

{
    "id": 1,
    "restaurant": "Burger King",
    "address": "Av. Ipiranga, 1600",
    "website": "https://www.burgerking.com.br/",
    "description": "Rede de fast-food famosa com hambúrgueres grelhados, batata frita e milk-shakes.",
    "count": 3
}

While McDonalds has 5 votes

{
    "id": 2,
    "restaurant": "McDonalds",
    "address": "Av. Ipiranga, 5200",
    "website": "https://www.mcdonalds.com.br/",
    "description": "Rede de fast-food tradicional conhecida por ter ótimos hambúrgueres e batatas fritas.",
    "count": 5
}

Here are the classes that I'm using:

Restaurant.java

package com.dbserver.restaurantes.entities;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnore;

@Entity
@Table(name = "db_restaurants")
public class Restaurant {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String restaurant;
    private String address;
    private String website;
    private String description;
    private Integer count;

    @JsonIgnore
    @OneToMany(mappedBy = "id.restaurant")
    private Set<Vote> votes = new HashSet<>();

    public Restaurant() {
    }

    public Restaurant(Long id, String restaurant, String address, String website, String description, Integer count) {
        this.id = id;
        this.restaurant = restaurant;
        this.address = address;
        this.website = website;
        this.description = description;
        this.count = count;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getRestaurant() {
        return restaurant;
    }

    public void setRestaurant(String restaurant) {
        this.restaurant = restaurant;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getWebsite() {
        return website;
    }

    public void setWebsite(String website) {
        this.website = website;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public Set<Vote> getVotes() {
        return votes;
    }

}

RestaurantDTO.java

package com.dbserver.restaurantes.dto;

import com.dbserver.restaurantes.entities.Restaurant;

public class RestaurantDTO {
    private Long id;
    private String restaurant;
    private String address;
    private String website;
    private String description;
    private Integer count;

    public RestaurantDTO() {
    }

    public RestaurantDTO(Long id, String restaurant, String address, String website, String description, Integer count) {
        this.id = id;
        this.restaurant = restaurant;
        this.address = address;
        this.website = website;
        this.description = description;
        this.count = count;
    }

    public RestaurantDTO(Restaurant restaurantDTO) {
        id = restaurantDTO.getId();
        restaurant = restaurantDTO.getRestaurant();
        address = restaurantDTO.getAddress();
        website = restaurantDTO.getWebsite();
        description = restaurantDTO.getDescription();
        count = restaurantDTO.getCount();
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getRestaurant() {
        return restaurant;
    }

    public void setRestaurant(String restaurant) {
        this.restaurant = restaurant;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getWebsite() {
        return website;
    }

    public void setWebsite(String website) {
        this.website = website;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
    
    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }   
}

RestaurantServices.java

package com.dbserver.restaurantes.services;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dbserver.restaurantes.dto.RestaurantDTO;
import com.dbserver.restaurantes.entities.Restaurant;
import com.dbserver.restaurantes.exceptions.NotFoundException;
import com.dbserver.restaurantes.repositories.RestaurantRepository;

@Service
public class RestaurantServices {

    @Autowired
    private RestaurantRepository repository;

    @Transactional(readOnly = true)
    public Page<RestaurantDTO> findAll(Pageable pageable) {
        Page<Restaurant> result = repository.findAll(pageable);
        Page<RestaurantDTO> page = result.map(x -> new RestaurantDTO(x));
        return page;
    }

    @Transactional(readOnly = true)
    public RestaurantDTO findById(Long id) {
        Restaurant result = repository.findById(id).get();
        RestaurantDTO dto = new RestaurantDTO(result);
        return dto;
    }

    @Transactional(readOnly = true)
    public Restaurant findWinner(Integer count) {
        List<Restaurant> restaurants = repository.findAll();

        for (Restaurant restaurant : restaurants) {
            // Hibernate.initialize(restaurant.getCount());
            if (restaurant.getCount() >= 3) {
                return restaurant;
            }
        }
        throw new NotFoundException(
                "Nenhum restaurante ganhou a votação, é necessário um total de 3 votos para ter um restaurante vencedor.");
    }   

    @Transactional
    public Restaurant addRestaurant(Restaurant newRestaurant) {
        return repository.saveAndFlush(newRestaurant);
    }

}

RestaurantRepository.java

package com.dbserver.restaurantes.repositories;

import org.springframework.data.jpa.repository.JpaRepository;

import com.dbserver.restaurantes.entities.Restaurant;

public interface RestaurantRepository extends JpaRepository<Restaurant, Long> {

}

RestaurantController.java

package com.dbserver.restaurantes.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.dbserver.restaurantes.dto.RestaurantDTO;
import com.dbserver.restaurantes.entities.Restaurant;
import com.dbserver.restaurantes.services.RestaurantServices;

@RestController
@RequestMapping(value = "/restaurants")
public class RestaurantController {

    @Autowired
    private RestaurantServices service;

    @GetMapping
    public Page<RestaurantDTO> findAll(Pageable pageable) {
        return service.findAll(pageable);
    }

    @GetMapping(value = "/{id}")
    public RestaurantDTO findById(@PathVariable Long id) {
        return service.findById(id);
    }
    
    @GetMapping(value = "/winner")
    public Restaurant findWinner(Integer count) {
        return service.findWinner(count);     
    };

    @PostMapping
    public Restaurant addRestaurant(@RequestBody Restaurant newRestaurant) {
        return service.addRestaurant(newRestaurant);
    }
    
}

CodePudding user response:

You have to check the top value as well. So You need to add your own query for that. Here is the code


public interface RestaurantRepository extends JpaRepository<Restaurant, Long>
{

    Optional<Restaurant> findFirstByCountGreaterThanEqualOrderByCountDesc (Integer count);

}

and Use that inside your method

@Transactional(readOnly = true)
    public Restaurant findWinner(Integer count) throws NotFoundException
    {
        Optional<Restaurant> data = repository.findFirstByCountGreaterThanEqualOrderByCountDesc(3);
        if (data.isPresent())
        {
            return data.get();
        }

        throw new NotFoundException("Nenhum restaurante ganhou a votação, é necessário um total de 3 votos para ter um restaurante vencedor.");
    }   

You can use native queries as well.

  • Related