Why are nested objects retrieved from a OpenFeign request to a Spring Data Rest endpoint null? - spring

I have the following domain classes in my client app:
#Value
public class Car {
private Long id;
private Model model;
}
#Value
public class Make {
private Long id;
private String name;
private Model model;
}
#Value
public class Model {
private Long id;
private String name;
}
My client app tries to get this data from a Spring Data Rest endpoint that return a HATEOAS response. The client does this via OpenFeign:
#FeignClient(name="car-service")
#Validated
public interface CarClient {
#GetMapping("/api/cars")
CollectionModel<Car> getAllCars();
}
But the each car has its make=null. How can I get make and model to be returned?

Related

Spring Requestbody JSON Deserializer not mapping the value

I have a problem where JSON data is not mapping to the Entity and it displays "selectedOption" as null.
Following Spring REST Contoller Method saves the order.
#RequestMapping(value = "/saveOrder")
public Long saveOrder(#RequestBody CustOrder order) {
return shopService.saveCustomerOrder(order);
}
Following is the JSON which is being sent to the method
{
"order":[
{
"selectedOption":{
"id":6,
"productOptionDescription":"Groß, Ø30cm:",
"optionPrice":null,
"optionPriceForSmall":null,
"optionPriceForNormal":6.7,
"optionPriceForFamily":null,
"optionPriceForParty":null,
"isDefault":true
}
}
]
}
Entity CustOrder
#Entity
public class CustOrder {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#OneToMany
#JoinColumn( name="custorder_id")
private Set<OrderItem> order=new HashSet<>();
}
Entity Order Item
#Entity
public class OrderItem {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#OneToOne
private ProductOption selectedOption;
}
I am struggling to understand why selectedOption is null.
Could someone help me with this.
Below is the screenshot from REST Controller Method (Eclipse)

How to post an Image and JSON object with single request to back end Spring Boot

I want to send image and JSON data to my back end in Spring Boot.
This is my method:
#PostMapping
public void uploadFile(#ModelAttribute FileUploadDto fileUploadDto) {
My FileUploadDto model:
public class FileUploadDto {
private MultipartFile file;
private CategoryModel category;
My CategoryModel model:
#Entity
#Table(name = "Category")
#JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
public class CategoryModel {
#Id
#Column(name = "id")
//#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String category_name;
private String category_description;
private String image_path;
#JsonIgnore
#OneToMany( mappedBy = "category")
private Set<ProductModel> category;
I do not understand where I'm wrong.
My postman request:
Your payload has to be raw and in json form. Something like this would help Spring boot to convert your payload into a object of an example class:
public class Foo{
public String foo;
public String foo1;
//Getters setters
}
And the request handling method:
#PostMapping
public void uploadFile(#RequestBody Foo foo)
It is also recommended to parse the payload into some a temporary class and then convert objects of the temporary class into the Entity class and vice versa. Take a look at: https://struberg.wordpress.com/2012/01/08/jpa-enhancement-done-right/ for more information
Also, if you want to upload file per REST I also recommend you to take a look at the following documentation: https://www.callicoder.com/spring-boot-file-upload-download-rest-api-example/
Best luck.

How to control JSON serialization result from same POJO?

I have a Spring Boot based application with Jackson for JSON serialization/deserizalization and JodaTime for LocalDate object.
I have a User class :
public class User {
private String firstname;
private String lastname;
private String email;
private LocalDate birthday;
// constructor, getter, setter...
}
I have two webservices which don't expose same fields.
For example:
WS1 will expose all fields and translate birthday in the "yyyy-MM-dd" format;
WS2 will expose only firstname, lastname and birthday fields and translate birthday in the "yyyy/MM/dd" format.
It will give me something like this:
public class View {
public interface Default {}
public interface All extends Default {}
}
public class User {
#JsonView(View.Default.class)
private String firstname;
#JsonView(View.Default.class)
private String lastname;
#JsonView(View.All.class)
private String email;
#JsonView(View.Default.class)
private LocalDate birthday;
}
#RestController
public class UserController {
#RequestMapping("/ws1/user")
#JsonView(View.All.class)
public User userSeenByWS1() {
return new User("john", "doe", "john.doe#unknown.com", LocalDate.now());
/*
Must return {"firstname":"john","lastname":"doe","email":"john.doe#unknown.com","birthday":"2017-07-27"}
*/
}
#RequestMapping("/ws2/user")
#JsonView(View.Default.class)
public User userSeenByWS2() {
return new User("john", "doe", "john.doe#unknown.com", LocalDate.now());
/*
Must return {"firstname":"john","lastname":"doe","birthday":"2017/07/27"}
*/
}
}
For now, I know that I can control fields serialization with #JsonView annotation and I can create two different ObjectMapper to control LocalDate serialization. But I don't know how to pass to the #JsonView the well defined objectMapper for each webservice.
I don't want to create 2 DTOs which represent each view of my User class. I want something that I can configure via annotation.

retrieving data from database as json in spring boot

I have a MySQL database and I want to retrieve some data as json.
And I have an entity Offre wich has #OneToMany relation with the AssociationCandidatOffre entity.
and I have an api which calles this method in my repository :
offreRepository.findAll();
Offre entity :
#Entity
public class Offre implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "CODE_OFFRE")
private Long codeOffre;
private String titre;
#OneToMany(mappedBy = "offre")
private Collection<AssociationCandidatOffre> associationCandidatOffres;
public Collection<AssociationCandidatOffre> getAssociationCandidatOffres() {
return associationCandidatOffres;
}
public void setAssociationCandidatOffres(Collection<AssociationCandidatOffre> associationCandidatOffres) {
this.associationCandidatOffres = associationCandidatOffres;
}
//... getters/setters
}
AssociationCandidatOffre entity :
#Entity
public class AssociationCandidatOffre implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long idAssociation;
private String lettreMotivation;
private String tarifJournalier;
private Date dateDisponibilite;
#ManyToOne
private Candidat candidat;
#ManyToOne
private Offre offre;
#JsonIgnore
#XmlTransient
public Candidat getCandidat() {
return candidat;
}
#JsonSetter
public void setCandidat(Candidat candidat) {
this.candidat = candidat;
}
#JsonIgnore
#XmlTransient
public Offre getOffre() {
return offre;
}
#JsonSetter
public void setOffre(Offre offre) {
this.offre = offre;
}
//... getters/setters
}
the problem is when I call the api /offres to return me a json object I get this error message instead :
Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: could not extract ResultSet (through reference chain: java.util.ArrayList[0]->com.***.Rekrute.entities.Offre["associationCandidatOffres"]);
nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not extract ResultSet (through reference chain: java.util.ArrayList[0]->com.***.Rekrute.entities.Offre["associationCandidatOffres"])
when I use #JsonIgnore in the getAssocationCandidatOffres I dont get any errors but I want that association in the json result as well.
Normally, this shouldn't generate any error since I have #JsonIgnore in the other side of the relation which is getOffre().
how can I solve this problem ?
You can't convert a bidirectional relation of an enitity to JSON.
You get an endless loop.
JSON-Parser starts with the entity Offer and reads the associated AssociationCandidatOffre via getAssociationCandidatOffres(). For every AssociationCandidatOffre the JSON-Parser read getOffre() and starts again. The parser don't know when he must end.

How to get the Prototype of Bean in Spring Boot

I am using Spring Boot and Spring Data JPA. I have created one entity as a Spring bean with prototype scope. How to I get the bean for each object to persist in database?
#Entity
#Table(name="sample")
#Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Sample {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
If I don't use the entity as Spring bean then I will use the following code to get the object:
Sample sample = new Sample();
How should I use the object using the Prototype scope bean in Spring Boot?
You dont want to define scope for entity. Entities are not like spring bean.
Spring data uses three important components for persisting into the database.
1) Entity Class - Each table has to be defined its own java object model called entity class.
#Entity
#Table(name="sample")
public class Sample {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#Column(name="name") //Column name from the table
private String name;
2) Repo Interface- In Which you can define own implementation of SQL, and it would have save method by default.
public interface SampleRepo extends CrudRepository<Sample,Long>{
List<Sample> findByName(String name);
}
3) Client program:
private SampleRepo s;
//instantiate s using autowired setter/constructor
....
//Select example
List<Sample> sampleList=s.findByName("example");
//Insert example
//Id is auto. So no need to setup explicit value for it.
Sample entity=new Sample();
s.setName("Example");
s.save(entity);

Resources