I using #MockMvc test in spring controller but i have a question.
How to handle message error when MockMvc test not pass method.
Entity:
#Entity
#ApiModel(description = "All details about the Product")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO,generator = "system-uuid")
#GenericGenerator(name = "system-uuid",strategy = "uuid2")
private String id;
#NotNull(message = "name can not null")
#ApiModelProperty(notes = "The name is product")
private String name;
#ApiModelProperty(notes = "The type is product")
private String type;
#NotNull(message = "category can not null")
private String category;
private String description;
private Double prince;
public Product() {
}
public Product(String name, String type, String category, String description, Double prince) {
this.name = name;
this.type = type;
this.category = category;
this.description = description;
this.prince = prince;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getPrince() {
return prince;
}
public void setPrince(Double prince) {
this.prince = prince;
}
#Override
public String toString() {
return "Product{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", type='" + type + '\'' +
", category='" + category + '\'' +
", description='" + description + '\'' +
", prince=" + prince +
'}';
}
}
StudentController:
#RestController
#RequestMapping("/products")
public class ProductController {
#PostMapping
public ResponseEntity<ProductDto> createProduct(#RequestBody Product product) {
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(product.getId()).toUri();
return ResponseEntity.created(location).body(productService.createProduct(product));
}
}
In above entity, I want using #MockMvc test createProduct. If name in product is null, i want show message in #MockMvc . It look like: "name can not null" . If pass, i don't want show it. Bellow my test:
#Test
public void givenProductURIWithPost_whenMockMVC_thenVerifyResponse() {
this.mockMvc.perform(post("/products")).andDo(print())
.andExpect(status().isOk()).andExpect(content()
.contentType("application/json;charset=UTF-8"))
}
I have two question:
1.How to show message "name can not null" if name in product is
null in #mockmvc.
2. If my project in 20 field in Products entity : Example: name,category.. I can test sequence field in Products or only test
one time contain all field.
Related
I'm new to this tool and I'm having trouble with this specific issue. I looked for an example But could not find something similar, better, I found a possible solution, but in my case It doesn't work.
I have this narrow project that resembles our famous CRUD, and I'm trying to reference the primary key from one table to another.
Client Entity:
#Entity
#Table(name = "client")
public class Client {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "cpf", length = 14)
private String cpf;
#Column(name = "name", length = 100)
private String name;
#Column(name = "birth_date")
private LocalDate birthDate;
#Column(name = "address", length = 255)
private String address;
#Column(name = "telephone", length = 14)
private String telephone;
#Column(name = "email", length = 200)
private String email;
#Column(name = "date_register", insertable = true, updatable = false)
private LocalDate dateRegister;
public Client() {
super();
}
public Client(Long id, String cpf, String name, LocalDate birthDate, String address, String telephone, String email, LocalDate dateRegister) {
super();
this.id = id;
this.cpf = cpf;
this.name = name;
this.birthDate = birthDate;
this.address = address;
this.telephone = telephone;
this.email = email;
this.dateRegister = dateRegister;
}
public Client(String cpf, String name, LocalDate birthDate, String address, String telephone, String email, LocalDate dateRegister) {
super();
this.cpf = cpf;
this.name = name;
this.birthDate = birthDate;
this.address = address;
this.telephone = telephone;
this.email = email;
this.dateRegister = dateRegister;
}
#PrePersist
public void prePersist() {
setDateRegister(LocalDate.now());
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCpf() {
return cpf;
}
public void setCpf(String cpf) {
this.cpf = cpf;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDate getBirthDate() {
return birthDate;
}
public void setBirthDate(LocalDate birthDate) {
this.birthDate = birthDate;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public LocalDate getDateRegister() {
return dateRegister;
}
public void setDateRegister(LocalDate dateRegister) {
this.dateRegister = dateRegister;
}
#Override
public String toString() {
return "Client [id=" + id + ", cpf=" + cpf + ", name=" + name + ", birthDate=" + birthDate + ", address="
+ address + ", telephone=" + telephone + ", email=" + email + ", dateRegister=" + dateRegister + "]";
}
}
Sale Entity:
#Entity
#Table(name = "sale")
public class Sale {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "client_id")
private Client client;
#OneToMany(mappedBy = "sale")
private List<SaleItem> items;
#Column(name = "payment_type", length = 10)
#Enumerated(EnumType.STRING)
private PaymentType paymentType;
#Column(name = "amount")
private BigDecimal amount;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public List<SaleItem> getItems() {
return items;
}
public void setItems(List<SaleItem> items) {
this.items = items;
}
public PaymentType getPaymentType() {
return paymentType;
}
public void setPaymentType(PaymentType paymentType) {
this.paymentType = paymentType;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
#Override
public String toString() {
return "Sale [id=" + id + ", client=" + client + ", items=" + items + ", paymentType=" + paymentType
+ ", amount=" + amount + "]";
}
}
The objective is to link the client to a sale through its primary key. These two codes refer to the sales repository and its controller:
SaleRepository:
public interface SaleRepository extends JpaRepository<Sale, Long> {
}
SaleController:
#RestController
#RequestMapping("/api/sales")
#CrossOrigin("*")
public class SaleController {
#Autowired
private SaleRepository repository;
#Autowired
private SaleItemRepository saleItemrepository;
#PostMapping
#Transactional
public void save(#RequestBody Sale sale) {
repository.save(sale);
sale.getItems().stream().forEach(saleItem -> saleItem.setSale(sale));
saleItemrepository.saveAll(sale.getItems());
}
}
And the problem is exactly how this reference is being made. In the current private Client client; way , the client object is being passed in full instead of its id, that's why it throws this following error when I try to register the sale.
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.time.LocalDate` from String "31/05/1968": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '31/05/1968' could not be parsed at index 0; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDate` from String "31/05/1968": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '31/05/1968' could not be parsed at index 0<EOL> at [Source: (PushbackInputStream); line: 1, column: 87] (through reference chain: MyNameIsRafaelSampaio.github.com.bruxo_vendas_ltda_api.model.Sale["client"]->MyNameIsRafaelSampaio.github.com.bruxo_vendas_ltda_api.model.Client["birthDate"])]
As was to be expected, since the column birthDate present in the client entity is not being treated correctly in the sale entity. I did research on a possible solution but none made much sense to me, I believe for being a newbie, one of the solutions that I found more understandable was the use of the #MapsId tag. I tried to make changes to adapt, but I was not successful, if you can help I will be grateful.
It was working fine until i added the Publisher, with has the anotation #manytoone.
Code from Book.java
package com.example.TDSSpringTest.domain;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
#Entity
public class Book {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
private String isbn;
#ManyToOne
private Publisher publisher;
#ManyToMany
#JoinTable(name = "author_book", joinColumns = #JoinColumn(name = "book_id"),
inverseJoinColumns = #JoinColumn(name = "author_id"))
private Set<Author> authors = new HashSet<>();
private Set<Publisher> publishers = new HashSet<>();
public Book (){
}
public Set<Publisher> getPublishers() {
return publishers;
}
public void setPublishers(Set<Publisher> publishers) {
this.publishers = publishers;
}
public Book(String title, String isbn) {
this.title = title;
this.isbn = isbn;
}
public Publisher getPublisher() {
return publisher;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public Set<Author> getAuthors() {
return authors;
}
public void setAuthors(Set<Author> authors) {
this.authors = authors;
}
#Override
public String toString() {
return "Book{" +
"id=" + id +
", title='" + title + '\'' +
", isbn='" + isbn + '\'' +
", authors=" + authors +
'}';
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Book book = (Book) o;
return id != null ? id.equals(book.id) : book.id == null;
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
}
Code from Publisher.java
package com.example.TDSSpringTest.domain;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
#Entity
public class Publisher {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String adressLine1;
private String city;
private String state;
private String zip;
#OneToMany
#JoinColumn(name = "publisher_id")
private Set<Book> books = new HashSet<>();
public Publisher(){
}
#Override
public String toString() {
return "Publisher{" +
"id=" + id +
", name='" + name + '\'' +
", adressLine1='" + adressLine1 + '\'' +
", city='" + city + '\'' +
", state='" + state + '\'' +
", zip='" + zip + '\'' +
'}';
}
public Set<Book> getBooks() {
return books;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Publisher publisher = (Publisher) o;
return id != null ? id.equals(publisher.id) : publisher.id == null;
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
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;
}
public String getAdressLine1() {
return adressLine1;
}
public void setAdressLine1(String adressLine1) {
this.adressLine1 = adressLine1;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
}
Error:
2021-09-03 11:34:21.454 ERROR 10844--- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: book, for columns: [org.hibernate.mapping.Column(publishers)]
package com.hashedin.employeemanagementsystem.entities;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
#Data
#Table(name="employee")
#Entity(name="User")
public class User{
public User(){
this.individual = new Individual();
this.workExperience = null;
this.experienceInMonths = null;
this.jobRole = null;
this.primaryContact = null;
this.secondaryContact = null;
this.employeeID = null;
this.joiningDate = null;
this.employeeCategory = null;
this.exitDate = null;
this.educationDetails = null;
}
#Id
//Employee 4 digit ID
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="employee_id")
private Long empID;
//employee ID Code
#Column(name = "employee_code_id")
private String employeeID;
#Embedded
#AttributeOverrides({
#AttributeOverride(name="first_name", column = #Column(name="employee_first_name")),
#AttributeOverride(name="last_name", column = #Column(name="employee_last_name")),
#AttributeOverride(name="email", column = #Column(name="employee_email")),
#AttributeOverride(name="phone", column = #Column(name="employee_phone")),
})
private Individual individual;
//Primary and Secondary Contacts
#Embedded
#AttributeOverrides({
#AttributeOverride(name = "email", column = #Column(name = "primary_contact_email")),
#AttributeOverride(name = "Individual.first_name", column = #Column(name = "primary_contact_first_name")),
#AttributeOverride(name = "last_name", column = #Column(name = "primary_contact_last_name")),
#AttributeOverride(name = "phone", column = #Column(name = "primary_contact_phone"))
})
private Individual primaryContact;
#Embedded
#AttributeOverrides({
#AttributeOverride(name="email", column = #Column(name="secondary_contact_email")),
#AttributeOverride(name="first_name", column=#Column(name="secondary_contact_first_name")),
#AttributeOverride(name="last_name", column=#Column(name="secondary_contact_last_name")),
#AttributeOverride(name="phone", column=#Column(name="secondary_contact_phone"))
})
private Individual secondaryContact;
//jobRole
#Embedded
private JobRole jobRole;
//joining date and exit date (mentioned for Fixed Employees / probation period)
#Column(name="joining_date")
private Date joiningDate;
#Column(name="exit_date")
private Date exitDate;
//category, experience and highest degree
#OneToOne(cascade = CascadeType.ALL)
private Education educationDetails;
#Column(name="employee_category")
private String employeeCategory;
#Column(name="total_experience")
private Integer experienceInMonths;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name="employee_id")
private List<Employment> workExperience;
public User(String firstName, String lastName, Location location, String email, String phone, String employeeID, Individual primaryContact, Individual secondaryContact, Date joiningDate, String employeeCategory, Date exitDate, Integer experience, Education educationDetails, JobRole jobRole, List<Employment> exp) {
this.individual = new Individual(firstName, lastName, location, email, phone);
this.workExperience = exp;
this.experienceInMonths = experience;
this.jobRole = jobRole;
this.primaryContact = primaryContact;
this.secondaryContact = secondaryContact;
this.employeeID = employeeID;
this.joiningDate = joiningDate;
this.employeeCategory = employeeCategory;
this.exitDate = exitDate;
this.educationDetails = educationDetails;
}
public Individual getIndividual() {
return individual;
}
public void setIndividual(Individual individual) {
this.individual = individual;
}
public Long getEmpID() {
return empID;
}
public void setEmpID(Long empID) {
this.empID = empID;
}
public Integer getExperienceInMonths() {
return experienceInMonths;
}
public void setExperienceInMonths(Integer experienceInMonths) {
this.experienceInMonths = experienceInMonths;
}
public List<Employment> getWorkExperience() {
return workExperience;
}
public void setWorkExperience(List<Employment> workExperience) {
this.workExperience = workExperience;
}
public JobRole getJobRole() {
return jobRole;
}
public void setJobRole(JobRole jobRole) {
this.jobRole = jobRole;
}
public Education getEducationDetails() {
return educationDetails;
}
public void setEducationDetails(Education educationDetails) {
this.educationDetails = educationDetails;
}
public Integer getExperience() {
return experienceInMonths;
}
public void setExperience(Integer experience) {
this.experienceInMonths = experience;
}
public Date getExitDate() {
return exitDate;
}
public void setExitDate(Date exitDate) {
this.exitDate = exitDate;
}
public String getEmployeeCategory() {
return employeeCategory;
}
public void setEmployeeCategory(String employeeCategory) {
this.employeeCategory = employeeCategory;
}
public String getEmployeeID() {
return employeeID;
}
public void setEmployeeID(String employeeID) {
this.employeeID = employeeID;
}
public Date getJoiningDate() {
return joiningDate;
}
public void setJoiningDate(Date joiningDate) {
this.joiningDate = joiningDate;
}
public Individual getPrimaryContact() {
return primaryContact;
}
public void setPrimaryContact(Individual primaryContact) {
this.primaryContact = primaryContact;
}
public Individual getSecondaryContact() {
return secondaryContact;
}
public void setSecondaryContact(Individual secondaryContact) {
this.secondaryContact = secondaryContact;
}
#Override
public String toString() {
return "User{" +
"empID=" + empID +
", employeeID='" + employeeID + '\'' +
", individual=" + individual.toString() +
", primaryContact=" + primaryContact +
", secondaryContact=" + secondaryContact +
", jobRole=" + jobRole +
", joiningDate=" + joiningDate +
", exitDate=" + exitDate +
", educationDetails=" + educationDetails +
", employeeCategory='" + employeeCategory + '\'' +
", experienceInMonths=" + experienceInMonths +
", workExperience=" + workExperience +
'}';
}
}
Still getting this error, please help:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boo
t/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceU
nit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.hashedin.emplo
yeemanagementsystem.entities.User column: email (should be mapped with insert="false" update="false")
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-5
.3.5.jar:5.3.5]
This is what my Individual class looks like:
package com.hashedin.employeemanagementsystem.entities;
import javax.persistence.*;
import java.lang.annotation.Target;
#Embeddable
public class Individual {
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
#Embedded
private Location location;
#Column(name="email")
private String email;
#Column(name="phone")
private String phone;
public Individual(){
this.firstName="";
this.lastName="";
this.location=null;
this.email=null;
this.phone=null;
}
public Individual(String firstName, String lastName, Location location, String email, String phone) {
this.firstName = firstName;
this.lastName = lastName;
this.location = location;
this.email = email;
this.phone = phone;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
#Override
public String toString() {
return "Individual{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", location=" + location +
", email='" + email + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
i am developing an API application, however I am having difficulties with a particular method.
The getCertificationPOJO method, is responsible for taking in a Store as a parameter and searching if that store exists in the database.
Now the problem here is how do I pass a Store object as a parameter in Postman. I have tried passing it in as a JSON string, but that is not working.
Apologies for the bad edit
Certification Controller
#Controller
public class CertController {
#Autowired
private CertificationRepository certRepo;
#Autowired
private StoreRepository StoreRepository;
#GetMapping(value = "/getCertObject")
public #ResponseBody
Optional<Certification> getCertificationPOJO(#RequestParam Store store)
{return Lists.newArrayList(certRepo.findAll()).stream().filter(e->e.getStore() == store).findFirst();}
}
Store Class
#Entity
#Table(name = "store")
public class Store implements com.halal.abstractions.Entity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#JsonIgnore
#OneToOne(optional = true) // By default this is set to true so technically this is redundant but, yea lets
// just keep it there
private Certification certification;
#NotNull
#Column(nullable = false)
private String name;
private String phoneNumber;
#NotNull
#Column(nullable = false)
private String address;
#NotNull
#Column(nullable = false)
private double latitude;
#NotNull
#Column(nullable = false)
private double longitude;
#NotNull
#Column(nullable = false)
private Date dateAdded;
static final DateFormat DF = new SimpleDateFormat("dd/MM/yyyy");
protected Store() {
}
public Store(String name, String phoneNumber, String address, double latitude, double longitude) {
this.name = name;
this.setPhoneNumber(phoneNumber);
this.setAddress(address);
this.latitude = latitude;
this.longitude = longitude;
this.dateAdded = new Date(System.currentTimeMillis());
}
#Override
public Long getId() {
return this.id;
}
#Override
public void setId(long id) {
this.id = id;
}
#Override
public String getName() {
return name;
}
#Override
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Double getLatitude() {
return this.latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public Double getLongitude() {
return this.longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
#Override
public String getDateAdded() {
return DF.format(dateAdded);
}
#Override
public void setCertification(Certification certification) {
this.certification = certification;
}
#Override
public Certification getCertification() {
return this.certification;
}
#Override
public String toString() {
return "Store{" + "id=" + id + ", certification=" + certification + ", name='" + name + '\'' + ", phoneNumber='"
+ phoneNumber + '\'' + ", address='" + address + '\'' + ", latitude=" + latitude + ", longitude="
+ longitude + ", dateAdded=" + dateAdded + '}';
}
}
Certification Class
#Entity
#Table(name = "certification")
public class Certification {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#NotNull
#Column(nullable = false)
private boolean isCertified;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "id")
#JsonIgnore
private Store store;
public Certification() {
}
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public Store getStore() {
return this.store;
}
public void setStore(Store store) {
this.store = store;
}
public boolean isIsCertified() {
return this.isCertified;
}
public void setIsCertified(boolean isCertified) {
this.isCertified = isCertified;
}
#Override
public String toString() {
return "Certification{" + "id=" + id + ", isCertified= " + isCertified + '}';
}
}
I would advise against sending a body in a GET request, see similar answer here
The query param route that #Murilo suggests is one way but if the way of determining whether a getCertificationPOJO already exists in the database depends solely on the id then you may only need to send the id in which case a path variable would be best like below where {id} can be replaced with the actual ID
GET /getCertObject/{id}
and then in the controller
#GetMapping("/getCertObject/{id}")
#ResponseBody
Optional<Certification> getCertificationPOJO(#PathVariable String id) {
...
}
You don't use Params section in this case. You use Body. Click on that tab and put your JSON OBJECT in the textbox that will appear. You also need to set CONTENT TYPE to JSON by selecting the proper value in the COMBO that appears farthest to the right of the attached image.
Check this out:
If you are using queryParams you have to pass individually each key/param, in your Postman you fill like it:
key: id value: 1
key: name value "asdasd"
key: phoneNumber value: "000"
(...)
Another option is you change your strategy and pass the entire json in your Body, but you will have to change your RestController to receive a #RequestBody instead of #RequestParam
I am having some issues according Hibernate.
I have a more or less complex object structure that I want to save / load using the Hibernate EntityManager (version 4.3.5.Final). I managed to save it, but if I attempt to read the obejct, only the PK will be read. The EntityManager's find method returns null even with the correct PK so I am using its getReference method.
I still have troubles using the correct relationship (ManyToOne and such) so I most likely made a mistake there and I guess that is causing the problem.
Anyways.
My question is: How do i persist an object structure like this using Hibernate?
Here are the POJOs i am using:
EDIT: Updated the Code
CalculationList:
#Entity(name = "calculation")
public class CalculationList implements EntityList {
#Id
private Date created;
#OneToMany(mappedBy = "", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Product> products;
public CalculationList(Date created) {
this.created = created;
this.products = new LinkedList<>();
}
public CalculationList(Date created, List<Product> products) {
this.created = created;
this.products = products;
}
public CalculationList() {
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> entities) {
this.products = entities;
}
#Override
public String toString() {
return "CalculationList{" +
"created=" + created +
", products=" + products +
'}';
}
}
CalulatorEntity:
#Entity(name = "calculator_entity")
public class CalculatorEntity implements Serializable {
#Id
private int id;
private CalculatorEntityType type;
private String name;
private int number;
#ManyToOne(cascade = CascadeType.ALL)
private Product product;
public CalculatorEntity(CalculatorEntityType type) {
this.type = type;
}
protected CalculatorEntity() {
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public CalculatorEntityType getType() {
return type;
}
public void setType(CalculatorEntityType type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public enum CalculatorEntityType {
GAS_PUMP, DELIVERY_BILL;
}
#Override
public String toString() {
return "CalculatorEntity{" +
"id=" + id +
", type=" + type +
", name='" + name + '\'' +
", product=" + product +
", number=" + number +
'}';
}
}
Product:
#Entity(name = "product")
public class Product implements Serializable {
#Id
private int id;
private String name;
private ProductType type;
#OneToMany(mappedBy = "product", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<CalculatorEntity> entities;
public Product(String name, ProductType type) {
this.name = name;
this.type = type;
this.entities = new LinkedList<>();
}
/**
* JPA - Konstruktor
*/
public Product() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ProductType getType() {
return type;
}
public void setType(ProductType type) {
this.type = type;
}
public List<CalculatorEntity> getEntities() {
return entities;
}
public void setEntities(List<CalculatorEntity> entities) {
this.entities = entities;
}
#Override
public String toString() {
return "Product{" +
"id=" + id +
", name='" + name + '\'' +
", type=" + type +
", entities=" + entities +
'}';
}
public enum ProductType {
FUEL("Treibstoff"), OIL("Öl"), OTHER("Verschiedenes");
private String name;
private ProductType(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
}
You are using the #OneToMany mapping with the wrong entity, instead of mapping Product class you are mapping CalculationList class, move the following configuration:
#OneToMany(mappedBy = "product", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<CalculatorEntity> entities;
to the Product class.