Kayd Anderson
Kayd Anderson

Reputation: 81

For loop on 2 lists and add to an object

Im looping over two lists and want to add the objects to a custom object. So Im getting an Employee a list of Projects and a list of Doubles from Thymeleaf and save them to a database. I want to save them to the object EmployeeProject which takes an Employee, a Project and a double (employeeBookedMonths). My problem is I either get the multiple projects saved to the EmployeeProject but all the project months are the same (the last double value one in the list) or I save the multiple projects to the employeeProject with correct employeeBookedMonths but there is dupicates, for example if I save 3 projects with 3 employeeBookedMonths, I get 3 times each saved (so 9 saved). I've tried moving the employeeProjectService.saveEmployeeProject but can't make it work plus many other variations but I need some help.

Question: how can I loop through the 2 lists and add and them to the EmployeeProject object? Without getting multiples or only getting the last employeeBookedMonths.

Thanks in advance.

Also the System.println prints the wanted values, they just don't save.

    public String saveEmployee(@ModelAttribute("employee") Employee employee,
                               @RequestParam("projectId") List<Project> projectIds,
                               @RequestParam("employeeProjectMonths") List<Double> months) {
        List<Double> monthList = new ArrayList<>();
        for (Double month : months) {
            if (month != null) {
                monthList.add(month);
                System.out.println("Month:" + month);
            }
        }
        employeeService.saveEmployee(employee);
        if (projectIds != null) {
            EmployeeProject employeeProject = new EmployeeProject(employee);
            for (Project ids : projectIds) {
                for (Double month : monthList) {
                    employeeProject.setEmployeeBookedMonths(month);
                    System.out.println("Months: " + employeeProject.getEmployeeBookedMonths());
                    employeeProjectService.saveEmployeeProject(employee, ids, month);
                }
            }
        }
        return "redirect:/ines/employees";
    }

New Employee form

<form action="#" th:action="@{/ines/saveEmployeeMeeting}" th:object="${employee}"
            method="POST" enctype="multipart/form-data">
            <div class="form-group">
                <label>Email:</label>
                <input type="text" th:field="*{name}"
                       placeholder="Employee Name" class="form-control mb-4 col-4">
            </div>
            <th:block th:object="${meetingInfo}">
                <div class="form-group">
                    <label>Start Time:</label>
                    <div class="input-group date" id="datetimepicker1" data-target-input="nearest">
                        <input type="text" class="form-control datetimepicker-input"
                               th:field="*{meetingStartDateTime}" id="meetingStartDateTime"/>
                        <span class="input-group-addon">
                            <span class="glyphicon glyphicon-calendar"></span>
                    </span>
                    </div>
                </div>
                <div class="form-group">
                    <label>End Time:</label>
                    <div class="input-group date" id="datetimepicker2" data-target-input="nearest">
                        <input type="text" class="form-control datetimepicker-input" data-target="#datetimepicker1"
                               th:field="*{meetingEndDateTime}" id="meetingEndDateTime" placeholder="Date"/>
                        <span class="input-group-addon">
                            <span class="glyphicon glyphicon-calendar"></span>
                    </span>
                    </div>
                </div>
            <div class="form-group">
                <input type="text" th:field="*{message}"
                       placeholder="Message" class="form-control mb-4 col-4">
            </div>
            </th:block>

            <button type="submit" class="btn btn-info col-2">Save Employee/Meeting</button>
        </form>

Employee

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

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

    @Column(nullable = false)
    private String name;

    @JsonFormat(pattern = "yyyy-MM-dd", shape = JsonFormat.Shape.STRING)
    @Column(name = "contracted_from")
    private String contractedFrom;

    @JsonFormat(pattern = "yyyy-MM-dd", shape = JsonFormat.Shape.STRING)
    @Column(name = "contracted_to")
    private String contractedTo;

    @OneToMany(mappedBy = "employee",
            cascade = CascadeType.ALL
//          fetch=FetchType.EAGER
    )
    private Set<EmployeeProject> employeeProjects = new HashSet<>();
// constructores getters and setters

Project

@Entity
@Table(name = "projects")
public class Project implements Serializable {
    @Id
    @Column(name = "project_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Long projectNumber;

    @Column(nullable = false, length = 45)
    private String name;


    @JsonFormat(pattern = "yyyy-MM-dd", shape = JsonFormat.Shape.STRING)
    @Column(name = "start_date", nullable = false)
    private String startDate;

    @JsonFormat(pattern = "yyyy-MM-dd", shape = JsonFormat.Shape.STRING)
    @Column(name = "end_date", nullable = false)
    private String endDate;

    @Column(name = "project_length_months")
    private double projectLengthInMonths;

    @Column(name = "project_booked_months")
    private double currentBookedMonths;

    @Column(name = "remaining_booked_months")
    private double remainingBookedMonths;

    private int numberOfEmployees;
    
    @OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
    private Set<EmployeeProject> employeeProjects = new HashSet<>();
// constructores getters and setters

EmployeeProject

@Entity
@Table(name = "employee_projects")
public class EmployeeProject implements Serializable {

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

    @ManyToOne
    @JoinColumn(name = "employee_id")
    private Employee employee;

    @ManyToOne
    @JoinColumn(name = "project_id")
    private Project project;

    @Column(name = "employee_booked_months")
    private double employeeBookedMonths;
// constructores getters and setters

Upvotes: 1

Views: 1177

Answers (3)

Kayd Anderson
Kayd Anderson

Reputation: 81

Its not the prettiest but it works, I feel a bit dumb after this one but if anyone has a more elegant approach I'm happy to see it.

@PostMapping("/saveEmployee")
    public String saveEmployee(@ModelAttribute("employee") Employee employee,
                               @RequestParam("projectId") List<Project> projectIds,
                               @RequestParam("employeeProjectMonths") List<Double> months) {

        List<Double> monthList = new ArrayList<>();
        for (Double month : months) {
            if (month != null) {
                monthList.add(month);
                System.out.println("Month:" + month);
            }
        }

        List<Project> projectList = new ArrayList<>();
        for (Project project : projectIds) {
            if (project != null) {
                projectList.add(project);
                System.out.println("Project:" + project);
            }
        }

        employeeService.saveEmployee(employee);
        for (int i=0; i<= monthList.size(); i++) {
            EmployeeProject employeeProject = new EmployeeProject(employee);
            employeeProject.setEmployeeBookedMonths(monthList.get(i));
            employeeProject.setProject(new Project(projectList.get(i).getId()));
            employeeProjectService.saveEmployeeProjectEmployeeOnly(employeeProject);
        }
        return "redirect:/ines/employees";
    }

The problem was I was getting the list of projectIds which also had the null values (not selected ones), so I had to create a list of the projects then use the i loop to set each Project and employeeProjectMonths.

Upvotes: 1

Lucas Favaro Borsatto
Lucas Favaro Borsatto

Reputation: 114

Did you consider that you're declaring EmployeeProject employeeProject = new EmployeeProject(employee); inside if (projectIds != null) { scope, so if you do println in the employeeProject, right above return "redirect:/ines/employees"; (outside the scope) you won't see it? In order to don't loose the data you need to declare employeeProject at the beginning of the method.

The follow code could correct this:

    public String saveEmployee(@ModelAttribute("employee") Employee employee,
                               @RequestParam("projectId") List<Project> projectIds,
                               @RequestParam("employeeProjectMonths") List<Double> months) {
        List<EmployeeProject> listOfEmployeeProjects = ArrayList<>();
        List<Double> monthList = new ArrayList<>();
        for (Double month : months) {
            if (month != null) {
                monthList.add(month);
                System.out.println("Month:" + month);
            }
        }
        employeeService.saveEmployee(employee);
        if (projectIds != null) {
            EmployeeProject employeeProject = new EmployeeProject(employee);
            for (Project ids : projectIds) {
                for (Double month : monthList) {
                    employeeProject.setEmployeeBookedMonths(month);
                    System.out.println("Months: " + employeeProject.getEmployeeBookedMonths());
                    employeeProjectService.saveEmployeeProject(employee, ids, month);
                }
            }
        listOfEmployeeProjects.add(employeeProject);
        }
    //Here you might see the data inside listOfEmployeeProjects, once it was declared in a outter scope
   //Maybe do a assign of your data to other field, for example: 
   // mainData.setAllOfTheEmployeeProjects(listOfEmployeeProjects);
        return "redirect:/ines/employees";
    }

Did it help? If didn't please post the rest of your code.

Upvotes: 0

Lucas Favaro Borsatto
Lucas Favaro Borsatto

Reputation: 114

In this line:

employeeProjectService.saveEmployeeProject(employee, ids, month);

it was supposed to save employee or employeeProject? Because in the code you didn't use the variable employeeProject explicitly. Where it was supposed to be saved?

Upvotes: 0

Related Questions