Dilara Daria
Dilara Daria

Reputation: 63

How can I perform findAllBy() using POST method?

I was asked to create a request that will list customers based on their genders. However the request method has to be POST and I was adviced to use a dto and a mapper to achieve this goal. I'll give some examples to further explain my problem.

My Customer entity is as follows:

@Data
@Entity
@Table(name = "customer", schema = "public")
public class Customer implements Serializable {
    @Id
    @Column(name = "id_", unique = true)
    private Integer id_;
    @Column(name = "name_", nullable = false)
    private String name_;
    @Column(name = "surname", nullable = false)
    private String surname;
    @Column(name = "phone", nullable = false)
    private String phone;
    @Column(name = "email", nullable = false)
    private String email;
    @Column(name = "gender", columnDefinition = "text", nullable = false)
    private String gender;
    @JsonBackReference
    @OneToMany(mappedBy = "customer")
    Set<PurchaseOrder> purchaseOrder = new HashSet();

    public Customer() {

    }

This is an example for customer stream based on my code:

{
        "id_": 1,
        "name_": "Laura",
        "surname": "Blake",
        "phone": "95334567865",
        "email": "Bulvar 216 PF Changs",
        "gender": "W"
    }

I am asked to give this stream as input:

{ "gender": "W" }

As an output I am expected to receive a list of customer entities with gender 'W'. So, I have created a CustomerDto class:

@Data
public class CustomerDto {
    private String gender;
}

This is the method I'm going to use defined in CustomerRepository:

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {

    List<Customer> findAllByGender(Customer customer);
}

This is what I have on my controller and service, respectively:

@RequestMapping(method= RequestMethod.POST, value="/customers/gender")
    public List<Customer> getCustomersByStream(@RequestBody @Valid Customer customer) {
        return service.getCustomersByGender(customer);
    }

public List<Customer> getCustomersByGender(Customer customer) {
        return repo.findAllByGender(customer);
    }

I added ModelMapper to my dependencies and I tried several methods both with customer and customerDto inputs. But I failed to successfully list customers by gender. I'd appreciate a code answer with proper explanations so that I can understand what's going on.

EDIT:

This is the answer without using ModelMapper. In case anyone is searching for a solution:

Controller:

@RequestMapping(method= RequestMethod.POST, value="/customers/gender")
    public List<Customer> getCustomersByStream(@RequestBody @Valid CustomerDto dto) {
        String gender = dto.getGender();
        return service.getCustomersByGender(gender);
    }

Repository:

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {

    List<Customer> findAllByGender(String gender);
}

Service:

public List<Customer> getCustomersByGender(String gender) {
        return repo.findAllByGender(gender);
    }

Upvotes: 2

Views: 94

Answers (1)

Amit Mishra
Amit Mishra

Reputation: 510

Okay, that's pretty simple.

In Your Controller

//Pass a parameter geneder = someValue and you will get that in the gender variable
@RequestMapping(method= RequestMethod.POST, value="/customers/gender")
public List<Customer> getCustomersByStream(@RequestBody AnotherDTO gender) {
    return service.getCustomersByGender(anotherDTO.getGender());
}

DTO's are meant to be used to accept a request body if they have a large data payload or for casting custom responses. As I think your superior would have asked to use a DTO for customizing response. Put only those varibles which you want to be there in the response.

ResponseDTO.java

public class CustomerDto {
    private String gender;
    private Long id;
    private String name;
    private String surname;
    private String phone;
    private String email;
    //Standard Setters and getters
    //Also, you need to make sure that the variable name in the Entity should 
    //be exactly same as your Entity. In DTO you just need to put those 
    //variables which you want to be in response.
}

Your Repo

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {

    List<Customer> findAllByGender(String gender);
}

Your Business layer. Some Java class.

public List<Customer> getCustomersByGender(String gender) {
    List<Customer> response = new ArrayList<>();
    List<Customer> list = repo.findAllByGender(gender);
    //Autowire Object mapper of manually create a new instance.
    ObjectMapper mapper = new ObjectMapper();
    list.forEach(customer ->{
         YourDTO ref = mapper.map(list, YourDTO.class);
         response.add(ref);
    });
   return response;
}

Now, you can simply return the response that you've received from the service layer.

Upvotes: 1

Related Questions