Webclient call returns entity ID with null value when the other part correctly - spring

I use WebClient to make calls between services by using Spring boot and Java 11. However, I receive the response entity with a null ID and the other parts have valid values. Whereas I have another call (WebClient) for another service and I receive the correct
response. How can I fix this issue in order to receive also the ID
#Getter
#Setter
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class Customer {
#JsonProperty("customer_id")
private Integer customerID;
private String name;
private String surname;
private Integer balance;
}
final String CUSTOMER_BASE_URL = "http://CUSTOMER-SERVICE/api/v1";
Customer customer = webClient.baseUrl(CUSTOMER_BASE_URL).build().get().uri("/customer/1")
.retrieve().toEntity(Customer.class).block().getBody();
Response:
customerID = null
name = "Renos"
surname = "Bardis"
balance = {Integer#16157} 100

Related

Got status 500 and message "Missing URI template variable 'rank'", whenever test HTTP POST request on postman

I got the error "Resolved [org.springframework.web.bind.MissingPathVariableException: Missing URI template variable 'rank' for method parameter of type Rank]" on eclipse console
And message: "Missing URI template variable 'rank' for method parameter of type Rank" with status "500" whenever try HTTP POST request
My RESTController code:
#RestController
#RequestMapping(path = "/comp")
public class RankController {
#PostMapping(path = "/rank")
ResponseEntity<Rank> createRank(#Valid #PathVariable Rank rank) throws URISyntaxException{
Rank result = rankRepository.save(rank);
return ResponseEntity.created(new URI("/comp/rank" + result.getId())).body(result);
}
}
My Rank entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "RANK_TBL")
public class Rank {
#Id
private Long id;
private String name;
#ManyToOne(cascade = CascadeType.PERSIST)
private Employee employee;
}
My Employee entity
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "EMPLOYEE_TBL")
public class Employee {
#Id
private Long id;
private String name;
private String email;
#OneToMany
private Set<Rank> Rank;
}
Change #PathVariable with #RequestBody
Here you are making a request to save the entity and you should pass the payload as #RequestBody in JSON format. From postman you may use raw type and select the JSON type.
Ideal way is to use #RequestBody whenever we are creating or updating the records which requires the object to passed with POST and PUT methods. For methods which retrieves the records based on Id or some parameters you may use #PathVariable
You may explore more about the annotations here

Passing parent id reference when creating child object through REST api

I am using spring boot (version - 2.1.1). I have a one to many database model exposed for CRUD operations through rest api's. The model looks as below. How do I configure the POST /departments api (that creates a department object) to accept just the organization id in the input json body?
#PostMapping
public Long createDepartment(#RequestBody Department Department) {
Department d = departmentService.save(Department);
return d.getId();
}
Note - I do not want to allow creating organization object when creating a department.
Model object mapping
#Entity
#Table(name="ORGANIZATIONS")
public class Organization{
#Id
#GeneratedValue
Private long id;
#Column(unique=true)
Private String name;
#OneToMany(mappedBy = "organization", fetch = FetchType.EAGER)
private List<Department> departments;
}
#Entity
#Table(name="DEPARTMENTS")
Public class Department{
#Id
#GeneratedValue
Private long id;
#Column(unique=true)
Private String name;
#ManyToOne(fetch = FetchType.EAGER)
private Organization organization;
}
Thanks!
The easiest and most sane way in my opinion is to utilize the DTO (Data Transfer Object) pattern.
Create a class that represent the model you want to get as your input:
public class CreateDepartmentRequest {
private long id;
// getters and setters
}
Then use it in your controller:
#PostMapping
public Long createDepartment(#RequestBody CreateDepartmentRequest request) {
Department d = new Department();
d.setId(request.getId());
Department d = departmentService.save(d);
return d.getId();
}
Side note, its better to ALWAYS return JSON through REST API (unless you use some other format across your APIs) so you can also utilize the same pattern as I mentioned above to return a proper model as a result of the POST operation or a simple Map if you don't want to create to many models.

Redis #Reference does not work in Spring Data Redis

I am facing issues while implemeting #Reference in Spring Boot + Spring Data Redis. Address is a List in Employee and when I saved the office and home address and I was expecting the data to be saved with the Employee. But data did not get saved and hence unable to search the Address using street.
Employee.java
#Builder
#Data
#AllArgsConstructor
#NoArgsConstructor
#RedisHash("employees")
public class Employee {
#Id #Indexed
private String id;
private String firstName;
private String lastName;
#Reference
private List<Address> addresses;
}
Address.java
#Builder
#Data
#AllArgsConstructor
#NoArgsConstructor
#RedisHash("address")
public class Address {
#Id
private String id;
#Indexed
private String street;
private String city;
}
Test class
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest
public class EmployeeAdressTest extends RepositoryTestSupport{
#Autowired private EmployeeRepository employeeRepository;
#Before
public void setUp() throws JsonProcessingException {
Address home = Address.builder().street("ABC Street").city("Pune").build();
Address offc = Address.builder().street("XYZ Street").city("Pune").build();
Employee employee1 = Employee.builder().firstName("Raj").lastName("Kumar").addresses(Arrays.asList(home, offc)).build();
employeeRepository.save(employee1);
List<Employee> employees = employeeRepository.findByAddresses_Street("XYZ Street");
System.out.println("EMPLOYEE = "+employees);
}
#Test
public void test() {
}
}
Spring Doc:
8.8. Persisting References
Marking properties with #Reference allows storing a simple key reference instead of copying values into the hash itself. On loading from Redis, references are resolved automatically and mapped back into the object, as shown in the following example:
Example 30. Sample Property Reference
_class = org.example.Person
id = e2c7dcee-b8cd-4424-883e-736ce564363e
firstname = rand
lastname = al’thor
mother = people:a9d4b3a0-50d3-4538-a2fc-f7fc2581ee56
Reference stores the whole key (keyspace:id) of the referenced object.
?
Spring Data Redis requires you to save the objects stored in home and office separately from the referencing object employee1.
This is (now) stated in the official documentation at the very end of chapter 8.8: https://docs.spring.io/spring-data-redis/docs/current/reference/html/#redis.repositories.references
So if you save home and office to the database before saving employee1 you should be fine.
The same btw holds valid for updates you make to referenced objects later on. Just saving the referencing object alone does not save the updates on the referenced objects.

How to add One to One relationship with an Embeddable

Requirement:
To fetch the list of requests along with the requests feedback status.
What I'm doing now :
Fetch all the requests using JPQL query. Loop through each request and fetch status and set into response dto.
What I want to doing.
Fetch all the request along with the status using JPQl query
What I'm looking for :
How can I add one to one mapping for requests & status, so that I can fetch status.
Sample code
This is the MSREQUEST entity
#Entity
#Table(name = "MSREQUEST")
public class Request implements Serializable {
#Id
private long requestId;
#Column(name = "DESC")
private string desc;
//getter.. setter...tostring and hashcode
}
This is the status entity
#Entity
#Table(name="FEEDBACKSTATUS")
public class FeedbackStatus implements Serializable {
// composite-id key
#EmbeddedId
private RequestFeedBackId requestFeedbackKey = new RequestFeedBackId();
#Column(name="STATUS")
private Long status;
//getter.. setter...tostring and hashcode
}
This is the embeddable entity
#Embeddable
public class RequestFeedBackId implements Serializable {
#Column(name="REQUESTID")
private Long requestId;
#Column(name="FEEDBACKID")
private Long feedbackId;
}
Service
#Override
public List<MsaRequestSearchDto> searchMsaRequests(MsaRequestSearchDto msaRequestSearchDto)
throws MsaException, Exception {
List<MsaRequestSearchDto> msaRequestSearchDtoList = msaRequestRepoCustom.findMsaRequests(msaRequestSearchDto);
*// get feedback status loop thru and fetch status for each one. nee to avoid this
if(msaRequestSearchDtoList != null && msaRequestSearchDtoList.size() > 0){
// code to fetch dstatus
}*/
return msaRequestSearchDtoList;
}
JPQL query that Im using..
public String GET_MSA_REQUEST = "SELECT dsr FROM Request dsr WHERE 1=1";
E-R

Spring Data MongoRepository save causing Duplicate Key error

Here is the Entity:
#Document
#Data
public class ApplicationUser {
private String name;
#Indexed(unique = true)
private String email;
private String organization = null;
// other fields
}
I fetch this user using their email and then change their name. I use the autowired instance of ApplicationUserRepository.
ApplicationUser applicationUser = applicationUserRepository.findByEmail("abc#gmail.com");
applicationUser.setName("John Doe 2");
Then I try to update this entity again in the database:
applicationUserRepository.save(applicationUser);
I get a duplicate key error on the field email. Why is this happening?
As far as I get from the documentation, the save method updates the same document if the ObjectId is the same. Since I haven't changed the objectId then why is it trying to create a new ApplicationUser during saving?
I got the solution.
When creating the entity, I have to explicitly declare the Id.
Here is the Entity:
#Document
#Data
public class ApplicationUser {
#Id
private ObjectId _id;
private String name;
#Indexed(unique = true)
private String email;
private String organization = null;
// other fields
}
I had similar issue where I was retrieving by id and then trying to update the retrieved POJO and then save it back with MongoRepository.save() call. It was on MongoDB 4.x with Spring Boot 2.1.0. I added the #Transactional annotation to my service method and everything worked like a charm. The duplicate key exception on id field was resolved.

Resources