Home > database >  Post Object with nested List object in Spring-boot and Thymeleaf
Post Object with nested List object in Spring-boot and Thymeleaf

Time:10-18

Spring/Thymeleaf beginner sorry in advance but I have 2 entities Employee and MeetingInfo. Employee has a oneToMany relationship with MeetingInfo so basically an Employee can have many MessageInfo. Using psvm I can add a new Employee with multiple MessageInfo to my database using something like this:

Employee employee1 = new Employee("Employee 1");
MeetingInfo mInfo1 = new MeetingInfo(LocalDate.of(2021, 1, 1), "First Random message");
MeetingInfo mInfo2 = new MeetingInfo(LocalDate.of(2021, 2, 2), "Second Random message");
MeetingInfo mInfo3 = new MeetingInfo(LocalDate.of(2021, 3, 3), "Third Random message");

employee1.getMeetingInfo().add(mInfo1);
employee1.getMeetingInfo().add(mInfo2);
employee1.getMeetingInfo().add(mInfo3);

employeeRepository.save(employee1);

But how can I do this with a form in thymeleaf? I can add just an employee, but cant add a new MeetingInfo object. When I do I get a passException error.

My new_employee.html

<form action="#" th:action="@{/ines/saveEmployee}" th:object="${employee}"
            method="POST">
            <input type="text" th:field="*{name}"
                placeholder="Employee Name" >
            *** so if I remove between here***
            <input type="date" th:field="*{meetingInfo.meetingDate}"
               placeholder="Message Date" >

            <input type="text" th:field="*{meetingInfo.message}"
               placeholder="Message" >
            *** and here***
            *** how can I include a MessageInfo object with a new Employee?***
            <button type="submit" >Save Meeting</button>
        </form>

My Controller

@GetMapping("/showNewEmployeeForm")
    public String showNewEmployeeForm(Model model) {
        Employee employee = new Employee();
        model.addAttribute("employee", employee);
        return "meeting/new_employee.html";
    }

    @PostMapping("/saveEmployee")
    public String saveEmployee(@ModelAttribute("employee") Employee employee) {
        employeeService.saveMessage(employee);
        return "redirect:/ines/employees";
    }

Employee

@Entity
@Table(name = "employee")
public class Employee {

    @Id
    @Column(name = "employee_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long employeeId;

    @Column(nullable = false)
    private String name;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "employee_id", referencedColumnName = "employee_id")
    private List<MeetingInfo> meetingInfo = new ArrayList<>();
//Constructors, getters and setters

MeetingInfo

@Entity
@Table(name = "meeting_info")
public class MeetingInfo {

    @Id
    @Column(name = "meeting_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long meetingId;

    private String message;


    @Column(name = "meeting_date")
    private LocalDate meetingDate;
//Constructors, getters and setters

CodePudding user response:

Saving multiple entities with a single request isn't something that you would usually want to do with your Spring Boot app, however, since I understand that this is for practice only, you could do this by using a single DTO object that would hold the information for both entities:

public class EmployeeMeetingDTO {

private String employeeName;

private String meetingMessage;

private LocalDate meetingDate;

}

Your controller could then accept just a single DTO entity from the request:

@PostMapping("/saveEmployee")
public String saveEmployee(@ModelAttribute("employeeDto") EmployeeMeetingDTO employeeDto) {
    employeeService.saveMessage(employeeDto);
    return "redirect:/ines/employees";
}

And you can separately create both entities in your EmployeeService class. Your Thymeleaf form would then look something like this:

<form action="#" th:action="@{/ines/saveEmployee}" th:object="${employeeDto}"
        method="POST">
        <input type="text" th:field="*{employeeName}"
            placeholder="Employee Name" >
       
        <input type="date" th:field="*{meetingDate}"
           placeholder="Message Date" >

        <input type="text" th:field="*{meetingMessage}"
           placeholder="Message" >
        
        <button type="submit" >Save Meeting</button>
    </form>
  • Related