RequestDto keep getting Null in Jpa - spring-boot

I'm trying to make invoice in my project.to make it, I need to POST all info that I already put in the DB. I'm trying to use #RequestBody using by requestDto but it keep getting null.
#Data
#Getter
public class InvoiceRequestDto {
private String note;
private AddressRequest addressRequest;
private BuyerRequest buyerRequest;
private SellerRequest sellerRequest;
private OrderRequest orderRequest;
other request in InvoiceRequestDto also look like this.
#Data
#Getter
public class BuyerRequest {
private String companyName;
private String email;
private String buyerManager;
private String buyerManagerNumber;
private String faxNumber;
this is service, I debugged in here and getting null from all requestDto in InvoiceRequestDto.
#Transactional
public Invoice postInvoice(InvoiceRequestDto invoiceRequestDto) {
try {
Buyer buyerPost = buyerRepository.findByBuyerManager(invoiceRequestDto.getBuyerRequest().getBuyerManager());
Seller sellerPost = sellerRepository.findBySellerManager(invoiceRequestDto.getSellerRequest().getSellerManager());
OrderItem orderPost = orderRepository.getByOrderNumber(invoiceRequestDto.getOrderRequest().getOrderNumber());
Invoice newInvoice = new Invoice(invoiceRequestDto.getNote(), orderPost, buyerPost, sellerPost);
Invoice saved = invoiceRepository.save(newInvoice);
return saved;
} catch (Exception e) {
e.printStackTrace();
return null;
}
this is controller.
#PostMapping("api/order/new")
public ResponseEntity<Long> postInvoice(#RequestBody InvoiceRequestDto invoiceRequestDto){
Long result = invoiceService.postInvoice(invoiceRequestDto).getId();
return ResponseEntity.ok(result);
this is Invoice Entity.
#Getter
#Entity
public class Invoice extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "invoice_id")
private Long id;
#ManyToOne
#JoinColumn(name = "buyer_id")
private Buyer buyer;
#ManyToOne
#JoinColumn(name = "seller_id")
private Seller seller;
#ManyToOne
#JoinColumn(name = "product_id")
private Product product;
#ManyToOne
#JoinColumn(name = "delivery_id")
private Delivery delivery;
#ManyToOne
#JoinColumn(name = "orderItem_id")
private OrderItem orderItem;
private boolean finalized;
private String note;
#Builder
public Invoice(String note, OrderItem orderPost, Buyer buyerPost, Seller sellerPost){
this.note = note;
this.orderItem = orderPost;
this.buyer = buyerPost;
this.seller = sellerPost;
}

Instead of using external class like this
#Data
#Getter
public class BuyerRequest {
private String companyName;
private String email;
private String buyerManager;
private String buyerManagerNumber;
private String faxNumber;
Try to use inner static classes in your InvoiceRequestDto like below and try again.
#Data
#AllArgsConstructor
#NoArgsConstructor
public class InvoiceRequestDto {
private String note;
private AddressRequest addressRequest;
private BuyerRequest buyerRequest;
private SellerRequest sellerRequest;
private OrderRequest orderRequest;
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class AddressRequest {
// neccessary fields
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class BuyerRequest {
// neccessary fields
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class SellerRequest {
// neccessary fields
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public static class OrderRequest {
// neccessary fields
}
}

Related

Post Request with Enum and composite key

I'm working on an exercise where i have to create CRUD operations.
I have a User table, a Role table and a UserRole table where i have the primary keys of those two entities.
I also have a RoleEnum with roles that have to be assigned to the User.
The problem that i'm gettin is that every time I insert a new user is a 200ok response but the role returns null and so it doesn't add it to the UserRole table as well.
I need help in solving the problem.
User Entity
#Data
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "utente")
public class Utente implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long matricola;
#Column(nullable = false)
private String nome;
#Column(nullable = false)
private String cognome;
#Column(nullable = false)
private String email;
#Column(name = "ruoloUtente", nullable = false)
#OneToMany(mappedBy = "matricolaUtente")
#JsonIgnore
private List<UtenteRuolo> ruoloUtente;
}
Role Entity
#Data
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "ruolo")
public class Ruolo implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "tipo_ruolo")
private String nome;
#Column(name = "utente_ruolo")
#OneToMany(mappedBy = "nomeRuolo")
private Set<UtenteRuolo> utenteRuolo;
}
UserRole class
#Data
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "utente_ruolo")
public class UtenteRuolo implements Serializable {
#EmbeddedId
private UtenteRuoloId utenteRuoloId;
#ManyToOne
#MapsId("matricola")
#JoinColumn(name = "matricola_utente", nullable = false)
private Utente matricolaUtente;
#ManyToOne
#MapsId("id")
#JoinColumn(name = "nome_ruolo", nullable = false)
private Ruolo nomeRuolo;
}
UserRoleId class
#Embeddable
#Data
#EqualsAndHashCode
#AllArgsConstructor
#NoArgsConstructor
public class UtenteRuoloId implements Serializable {
#Column(name = "matricola")
private Long matricola;
#Column(name = "id")
private Long id;
}
RoleEnum class
public enum RuoliEnum {
#JsonProperty
REFERENTE("REFERENTE"),
CONSULTATORE("CONSULTATORE"),
APPROVATORE("APPROVATORE");
#JsonProperty
private String value;
RuoliEnum(String value) { this.value = value; }
#JsonCreator
public static RuoliEnum fromValue(String text) {
for (RuoliEnum ruoli: RuoliEnum.values()) {
if (String.valueOf(ruoli.value).equalsIgnoreCase(text.trim())) {
return ruoli;
}
}
return null;
}
}
I also have all DTO's and the UserDTO has the RoleEnum instead of the List of class UserRole.
UserService
#Service
public class UtenteService {
#Autowired
private UtenteRepository utenteRepository;
#Autowired
private UtenteMap utenteMap;
public UtenteDto addUtente(UtenteDto utente) {
Utente u = utenteMap.fromDtoToModel(utente);
if(u != null) {
return utenteMap.fromModelToDto(utenteRepository.save(u));
}
return null;
}
UserController
#RestController
#RequestMapping("utente")
public class UtenteController {
#Autowired
private UtenteService utenteService;
#PostMapping("/addUtente")
public ResponseEntity addUtente(#Nullable #RequestBody UtenteDto utente) {
if(utente != null) {
return ResponseEntity.ok(utenteService.addUtente(utente));
} else {
return ResponseEntity.badRequest().body("utente non inserito correttamente");
}
}
this is a postman insert example:
{
"matricola" : 11,
"nome" : "aaa",
"cognome" : "bb",
"email" : "eee#mail.com",
"ruolo" : "APPROVATORE"
}
and this is the postman response with 200ok status:
{
"matricola": 11,
"nome": "aaa",
"cognome": "bb",
"email": "eee#mail.com",
"ruolo": null
}
the code doesn't tell me about any kind of error and i need to keep the UserRole table because it's required for this kind of exercise.
I tried everything I could but since I never worked like this with enums and this kind of table relations I don't know what's missing to complete it.

how to properly design a controller and a jsp page for an entity that has three keys, two external and one internal?

I'm trying to make a Spring MVC application.I have 4 entities(Company,Pass_in_trip,Passenger,Trip) Pass_in_trip has 3 keys consisting of Passenger, Trip and Timestamp, I don't know how to properly issue a key and how to transfer it through the jsp page to the controller, and how to issue the controller itself, can anyone tell me?and also an interesting question is how to make a request to the database to search for a record using three keys.
Thanks
here's what I was able to write at the moment, see if there are any errors somewhere
#Entity
#Table(name="company")
public class Company implements Serializable {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name="id_comp")
private int id_comp;
#Column(name="name")
private String name;
//Getters and Setters
#Entity
#Table (name="pass_in_trip")
public class Pass_in_trip implements Serializable {
#EmbeddedId
private KeysPass_in_trip key=new KeysPass_in_trip();
#Column(name="place")
private String place;
//Getters and Setters
#Embeddable
public class KeysPass_in_trip implements Serializable{
#NotNull
#JoinColumn(name="date")
private Timestamp date=new Timestamp(System.currentTimeMillis());
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "id_psg")
private Passenger id_psg=new Passenger();
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "trip_no" )
private Trip trip_no=new Trip();
//Getters and Setters
//#Override hashCode and equals
#Entity
#Table(name="passenger")
public class Passenger implements Serializable {
#Column(name="name")
private String name;
#NotNull
#Id
#Column(name="id_psg")
#GeneratedValue(strategy = IDENTITY)
private int id_psg;
//Getters and Setters
#Entity
#Table(name="trip")
public class Trip implements Serializable {
#NotNull
#Id
#Column(name="trip_no")
private int trip_no;
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "id_comp")
private Company comp=new Company();
#Column(name="plane")
private String plane;
#Column(name="town_from")
private String town_from;
#Column(name="town_to")
private String town_to;
#Column(name="time_out")
private Timestamp time_out;
#Column(name="time_in")
private Timestamp time_in;
//Getters and Setters
Conroller
#Controller
#RequestMapping("/pass_in_trip/")
public class Aero_Controller_Pass_in_trip {
#Autowired
private Aero_DAO service;
public void setService(Aero_DAO service) {
this.service = service;
}
#RequestMapping(method=RequestMethod.GET)
public String list(Model uiModel) {
List <Pass_in_trip> pass_in_trip=service.findallPass_in_trip();
uiModel.addAttribute("pass_in_trip",pass_in_trip);
return "/pass_in_trip/list";
}
#PreAuthorize("hasRole('ROLE_Admin')")
#RequestMapping(value="delete/{id}",method=RequestMethod.GET)
public String delete(#PathVariable("id")int id, Model uiModel) {
if(service.findByIdPass_in_Trip(id)!=null)
service.delete_Pass_in_trip(id);
return "redirect:/pass_in_trip/";
}
#PreAuthorize("hasRole('ROLE_Admin')")
#RequestMapping(value="update/{id}",method=RequestMethod.GET)
public String updateform(#PathVariable("id")int id, Model uiModel) {
System.out.println("upform");
uiModel.addAttribute("pass_in_trip",service.findByIdPass_in_Trip(id));
System.out.println("upform2");
return "/pass_in_trip/edit";
}
#RequestMapping(value="update/0",method=RequestMethod.GET)
public String newform(Model uiModel) {
System.out.println("Привет!");
return "/pass_in_trip/edit";
}
#PreAuthorize("hasRole('ROLE_Admin')")
#RequestMapping(value="update/{id}",method = RequestMethod.POST)
public String update(Pass_in_trip pass_in_trip,BindingResult bindingResult,Model uiModel,HttpServletRequest httprervletrequest , RedirectAttributes redirectatributes) {
if (bindingResult.hasErrors()) {
uiModel.addAttribute("pass_in_trip", pass_in_trip);
return "pass_in_trip/update";}
service.save(pass_in_trip);
return "redirect:/pass_in_trip/";
}
}
List.jsp
interested in this part:
<s:authorize access="hasRole('ROLE_Admin')">
<td> To change </td>
<td> Delete </td>
</s:authorize>

Spring Controller Returns Object Incompletely

There are three classes (Course, Lesson, User).
#EqualsAndHashCode(callSuper = true)
#Entity
#Table(name = "usr")
#Data
public class User extends RepresentationModel<User> implements UserDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstname;
private String lastname;
private String username;
private String password;
#ElementCollection(targetClass = ERole.class, fetch = FetchType.EAGER)
#CollectionTable(name = "user_role", joinColumns = #JoinColumn(name = "user_id"))
#Enumerated(EnumType.STRING)
private Set<ERole> roles;
}
#Data
#Entity
#NoArgsConstructor
public class Lesson extends RepresentationModel<Lesson> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String startTime;
private String endTime;
private String dayOfWeek;
#ManyToOne
private User teacher;
}
#EqualsAndHashCode(callSuper = true)
#Data
#Entity
public class Course extends RepresentationModel<Course> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Date startDate;
private Date endDate;
private String name;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<User> teachers;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<User> students;
private String description;
#ManyToMany(cascade = CascadeType.ALL)
private Set<Lesson> lessons;
}
And also RestController (CoursesController). When accessing the server at /courses, I get the correct server response with all fields
.
#RestController
#RequestMapping("/courses")
public class CoursesController {
private final CourseService courseService;
private final UserService userService;
private final LessonService lessonService;
#Autowired
public CoursesController(CourseService courseService, UserService userService, LessonService lessonService) {
this.courseService = courseService;
this.userService = userService;
this.lessonService = lessonService;
}
#GetMapping
#Operation(
summary = "getAllCourses",
description = "Returns all available courses"
)
public ResponseEntity<Page<Course>> getAllCourses(#PageableDefault(sort = "id", size = 5) Pageable pageable) {
try {
Page<Course> coursePage = courseService.findAll(pageable);
for (Course course : coursePage.getContent())
course.add(linkTo(methodOn(CoursesController.class).getCourse(course.getId().toString())).withSelfRel());
return ResponseEntity.ok(courseService.findAll(pageable));
}
catch (Exception e) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
#GetMapping("/{course-id}")
#Operation(
summary = "getCourse",
description = "Returns course by ID"
)
public ResponseEntity<Course> getCourse(#PathVariable ("course-id") String courseId) {
try {
Course course = courseService.getCourseById(courseId);
course.add(linkTo(methodOn(CoursesController.class).getCourse(courseId)).withSelfRel());
return ResponseEntity.ok(course);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
}
Why, when requesting a course by ID (GET /courses/{id}), does Spring return an incomplete object (despite the fact that I manually added several teachers, students and lessons)?
I need to get all the fields of my object.
My CourseRepository below.
#Repository
#Transactional
public interface CourseRepository extends JpaRepository<Course, Long> {
}
My CourseService below.
#Service
public class CourseService {
private final CourseRepository courseRepository;
private final LessonRepository lessonRepository;
private final UserRepository userRepository;
#Autowired
public CourseService(CourseRepository courseRepository, LessonRepository lessonRepository, UserRepository userRepository) {
this.courseRepository = courseRepository;
this.lessonRepository = lessonRepository;
this.userRepository = userRepository;
}
public Page<Course> findAll(Pageable pageable) {
return courseRepository.findAll(pageable);
}
public Course createCourse(CourseDto courseDto) {
Course course = new Course(courseDto.getStartDate(), courseDto.getEndDate(), courseDto.getName(), courseDto.getDescription());
return courseRepository.saveAndFlush(course);
}
public Optional<Course> getCourseById(String id) {
return courseRepository.findById(Long.parseLong(id));
}
public Course updateCourse(CourseDto courseDto, String id) {
Course course = courseRepository.findById(Long.parseLong(id)).get();
course.setStartDate(courseDto.getStartDate());
course.setEndDate(courseDto.getEndDate());
course.setName(courseDto.getName());
course.setDescription(courseDto.getDescription());
return courseRepository.saveAndFlush(course);
}
public Page<Lesson> getLessonsByCourse(String courseId, Pageable pageable) {
Course course = courseRepository.findById(Long.parseLong(courseId)).get();
return new PageImpl<>(new ArrayList<>(course.getLessons()), pageable, course.getLessons().size());
}
public Course addLesson(String courseId, LessonDto lessonDto) {
Course course = courseRepository.findById(Long.parseLong(courseId)).get();
Lesson lesson = new Lesson();
lesson.setStartTime(lessonDto.getStartTime());
lesson.setEndTime(lessonDto.getFinishTime());
lesson.setDayOfWeek(lessonDto.getDayOfWeek());
lesson.setTeacher(userRepository.getUserById(lessonDto.getTeacherId()));
lessonRepository.saveAndFlush(lesson);
System.out.println(lesson);
course.getLessons().add(lesson);
return courseRepository.saveAndFlush(course);
}
public void deleteCourse(String id) {
courseRepository.deleteById(Long.parseLong(id));
}
}
Which I would (or might) expect as well. I would links to be generated for those additional relationshps (at least normally with Spring Data RESt handling this is what would happen). I wonder what happens if you ditch the RepresentationModel from your JPA model and just expose Course then. As stated you don't really want your JPA and HATEOAS stuff to be intertwined. You want to have a specialized projection/dto to expose. WHy does it work for your findAll. well you aren't adding links to it (although you think it does but your findAll executes twice!).
Removed RepresentationModel from User class.
Thx to #M.Deinum

AuditingEntityListener is not working for the entity that extends another abstract entity in spring jpa

I have used the #CreatedBy, #CreatedDate, #LastModifiedBy, and #LastModifiedDate annotation on their respective fields. By using #MappedSuperclass,#EntityListeners i able to persist above columns.
But this is not working for the below case:
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class Auditable<U> {
#CreatedBy
protected U createdBy;
#CreatedDate
#Temporal(TIMESTAMP)
protected Date creationDate;
#LastModifiedBy
protected U lastModifiedBy;
#LastModifiedDate
#Temporal(TIMESTAMP)
protected Date lastModifiedDate;
}
#Entity
#Table(name = "tabel1")
#PrimaryKeyJoinColumn(name = "ID")
class A extends B {
#Column(name = "NAME1", nullable = false)
private String name1;
#Column(name = "CONTENT1", nullable = false)
private String content1;
}
#Entity
#Table(name = "tabel2")
public abstract class B extends Auditable{
#Id
#GeneratedValue
#Column(name = "ID", nullable = false)
private int id;
#Column(name = "NAME", nullable = false)
private String name;
#Column(name = "CONTENT", nullable = false)
private String content;
}
AuditorAwareImpl.java
public class AuditorAwareImpl implements AuditorAware<String>
{
#Override
public Optional<String> getCurrentAuditor()
{
return Optional.ofNullable("Saravanan");
}
}
JpaAuditConfiguration.java
#Configuration
#EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class JpaAuditConfiguration
{
#Bean
public AuditorAware<String> auditorProvider()
{
return new AuditorAwareImpl();
}
}
In the case, Entity B is populated with audit columns. But Entity A is not. Is there a way to populate Entity A or did i missed anything here..??
I added #Entity annotation to your classes:
#Entity
public class A extends B {
#Id
#GeneratedValue
private Integer id;
private String name;
private String content;
}
#Entity
public class B extends Auditable<String> {
#Id
#GeneratedValue
private Integer id;
private String name;
private String content;
}
Persistence config class (for Spring Boot):
#Configuration
#EnableJpaAuditing
public class PersistenceConfig {
}
Everything works perfectly!

Why is my mapped DTO List null? What is the best way to map and persist Child Lists?

I have a simple problem - but I think "I am standing on the tube".
I have a spring boot rest api with JPA, Modelmapper, Entities and DTOs.
But the mapping doesn't work.
Entities:
#Getter
#Setter
#MappedSuperclass
public class AbstractEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
#Getter
#Setter
#Entity(name = "contacts")
public class Contact extends AbstractEntity {
#NotBlank
private String firstName;
#NotBlank
private String lastName;
#Valid
#OneToMany(mappedBy = "contact", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PhoneNumber> phoneNumberList;
}
#Getter
#Setter
#Entity(name = "phone_numbers")
public class PhoneNumber extends AbstractEntity {
#NotBlank
private String label;
#NotBlank
private String number;
#ManyToOne
#JoinColumn(name = "contact_id", referencedColumnName = "id")
#Setter(value = AccessLevel.NONE)
private Contact contact;
}
The DTOs:
#Getter
#Setter
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class ContactDTO {
private Long id;
private String firstName;
private String lastName;
List<PhoneNumberDTO> phoneNumberDTOList = new ArrayList<>();
}
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class PhoneNumberDTO {
private Long id;
private String label;
private String number;
}
My ModelMapperConfig:
#Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(AccessLevel.PRIVATE);
return modelMapper;
}
Repo:
public interface ContactRepository extends JpaRepository<Contact, Long{
}
Service (only the create method):
#Override
public ContactDTO createOne(ContactDTO contactDTO) {
Contact contact = modelMapper.map(contactDTO, Contact.class);
contactRepository.save(contact);
return contactDTO;
}
Is this the correct way to persist the Contact with its multiple phonenumbers?
And how can I create a simple mapping?
If i want to persist it, there comes an error:
Column 'contact_id' cannot be null

Resources