Use unique id to deserialize object via json - spring

I have the following Spring JPA POJO:
#Entity
public class Employee {
private String firstname;
private String lastname;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
}
Without going into details, it is easy via Spring MVC to deserialize the following JSON to Employee object instance
{
"id": 1,
"firstName": "Peter",
"lastName": "Jones"
}
My questios: since each employee has a unique id, is it possible to only send only the employee id via JSON, and somehow via Spring JPA, and Jackson magic to retrieve the rest of the information
{
"id": 1
}
The function that would deserialize JSON to object would be:
#RequestMapping(method = RequestMethod.POST, path = "/update")
public void updateFilter(#RequestBody Employee emp) {
employeerepo.save(emp);
}
Technically, I can write a function to do the mapping and such, but I have a feeling that someone else had this problem before and there is clean and elegant way to do it without much coding

Related

How to pass the ID of a foreign field when using Rest API in Spring/JPA

I'm making a RestAPI using Spring/JPA, and I'd like to insert a new object into the database.
My object is designed like this:
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String street;
private Integer number;
#Column(name = "postal_code")
private String postalCode;
#ManyToOne(fetch = FetchType.LAZY)
#JsonBackReference
#JoinColumn(name = "city_id")
private City city;
}
So when I pass the ID through the body of the request using the RequestBody annotation, it does not get mapped to the field city, since it is not an Integer, rather of type City.
So when passing the following input:
{
"city": "1",
"street": "dobrota",
"number": "2",
"postalCode": "85330"
}
It returns JSON parse error: Cannot construct instance of com.ct.academy.entities.City (although at least one Creator exists) no String-argument constructor/factory method to deserialize from String value
Is there a way of getting the ID from the body, without changing the structure of my entity, or using a DTO, since I'm planning to set the City inside of the method in the service class?

How to add new fields / values to an existing entity in Spring Data JPA

How can I add new fields or values or properties to an existing entity and store them in the same table?
Customer entity already exists and have fields as
- id
- name
- lastName
Want to add contactNumber (as seen in the api structure below) to this existing Customer entity. Don't want a new entity for contactNumber
The expected request body is as below:
{
"id": "int auto generated",
"name": "String",
"lasName": "String",
"contactNumber":
{
"mobile":"long",
"office":"long",
"home":"long"
}
}
How can this be achieved ? Checked some blogs related to mapstruct but not getting proper solution.
You can use #Embeddable :
#Embeddable
public class ContactNumber {
private Long mobile;
private Long office;
private Long home;
// getters, setters...
}
Customer Entity:
#Entity
public class Customer {
#Id
private Long id;
private String name;
private String lastName;
#Embedded
private ContactNumber contactNumber;
// getters, setters...
}
With this mapping three columns(mobile, office, home) will be added to the Customer table.
You can simply save the Customer with the request body in the question using (#RequestBody Customer customer) parameter:
#PostMapping(value="/customers")
public void saveCustomers(#RequestBody Customer customer) {
customerRepository.save(customer);
}
For more information take a look at here.

Spring Boot List of Object Bean Validation

I have a Bean,
#Data
#NoArgsConstructor
public final class PersonRequest {
#NotNull
#JsonProperty("nameList")
private List<Person> nameList;
}
and Person POJO,
#Data
public class Sensor {
#NotNull
#JsonProperty("id")
private int id;
#NotNull
#JsonProperty("name")
#Min(1)
private String name;
}
I am sending JSON request and added #Valid in my controller. I am sending request as below,
{
"nameList": [
{
"id": 1,
"name": "John"
},
{
"id": 2,
"name": "Alex"
}
]
}
When i send request without id and name not validating. I tried using #Valid private List<Person> nameList; also but no luck. I use Spring boot 2.3.2.
UPDATED:
when i add one more attribute, this also say bad request when i pass date in request.
#NotNull
#JsonProperty("startTime")
#DateTimeFormat(pattern = "yyyy-MM-dd'T'hh:mm:ss", iso =
DateTimeFormat.ISO.DATE_TIME)
#Valid
private LocalDateTime startTime;
The #Valid annotation in your controller triggers the validation of the PersonRequest object, passed as request body. To validate also the Person objects contained in PersonRequest, you need to annotate that field with #Valid too.
#Data
#NoArgsConstructor
public final class PersonRequest {
#NotNull
#JsonProperty("nameList")
#Valid
private List<Person> nameList;
}

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.

Spring boot validate multiple object from map

I want to validate more than one entity before create or update. I have done these simply with custom validator in Grails. I'm wondering is there any way to do custom validator in spring which will take constraints (#NotNull, #Size etc) from entity.
Example entities:
Employee:
#Entity
class Employee{
#NotNull
String firstName
#NotNull
String lastName
#NotNull
Date dob
#ManyToOne
#JoinColumn(name = "contact_id", nullable = true)
Contact contact
}
Contact:
#Entity
class Contact{
#NotNull
String mobile
#NotNull
String email
}
Controller method:
#RequestMapping(method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
ResponseEntity create(#RequestBody Map<String, Object> payload) {
Employee employee = new Employee()
Contact contact = new Contact()
//assign some properties before validation
//validate employee and contact
// create employee and contact
}
JSON request:
{
"employee": {
"firstName": "abc",
"lastName": "def",
"contact": {
"mobile": "9876543210",
"email": "email#example.com"
}
}
}
I want to do custom validation like, if contact object is present, then validate, its properties. If DOB is greater than particular date, then expect some properties etc.

Resources