2

I'm trying to build a little project-management tool as my first Spring Boot / JPA / H2 / REST Application using lombok annotations for avoiding boilerplate-code. I followed several promising tutorials. But I'm failing at the very end, when I try to intantiate some dummy data to test the database and start the service.

Till now it had two tables: "T_PROJECT" & "T_EMPLOYEE"

But I also want to be able to visualize, in which period an employee works for a specific project. So I need a third table "T_EMPLOYEE_ACTIVITY" with two extra columns: "START_DATE" & END_DATE".

I made an
ER-Diagram that should help to understand how these tables must work together.

I found already this one here: JPA 2.0 many-to-many with extra column

... and tried to build it the same way:

The Project entity:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "T_PROJECT")
public class Project implements Serializable {

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

    @Column(name = "START_DATE")
    private String startDate;

    @Column(name = "END_DATE")
    private String endDate;
    private Status status;

    @OneToMany(mappedBy = "project")
    @Column(name = "EMPLOYEE_ACTIVITIES")
    private Set<EmployeeActivity> employeeActivities;
}

The Employee entity:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "T_EMPLOYEE")
public class Employee implements Serializable {

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

    @Column(name = "FIRST_NAME")
    private String firstName;

    @Column(name = "LAST_NAME")
    private String lastName;
    private String role;

    @Column(name = "HOURS_PER_WEEK")
    private BigDecimal hoursPerWeek;

    @OneToMany(mappedBy = "employee")
    @Column(name = "EMPLOYEE_ACTIVITIES")
    private Set<EmployeeActivity> employeeActivities;
}

EmployeeActivity entity:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "T_EMPLOYEE_ACTIVITY")
public class EmployeeActivity implements Serializable {

    @Id
    @Column(name = "EMPLOYEE_ACTIVITY_ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @ManyToOne
    @JoinColumn(name = "PROJECT_ID")
    private Project project;

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

    @Column(name = "START_DATE")
    private String startDate;

    @Column(name = "END_DATE")
    private String endDate;
}

In the Application.java (with main & run method), I tried to intantiate it like this and failed:

    @Override
    public void run(String... args) throws Exception {

        Project project = new Project(null, "BERLIN_AIRPORT", "2006-05-01", "2020-10-31", Status.COMPLETED, Set.of( ??? ));
        projectRepository.save(project);

        Employee employee = new Employee(null, "Jim", "Beam", "Architect", BigDecimal.valueOf(40d), Set.of( ??? ));
        employeeRepository.save(employee);

        EmployeeActivity employeeActivity = new EmployeeActivity();
        employeeActivity.setProject(project);
        employeeActivity.setEmployee(employee);
        employeeActivity.setStartDate("2006.05.01");
        employeeActivity.setEndDate("2010.12.12");
        employeeActivityRepository.save(employeeActivity);
    }

So both - Project and Employee - have an attribute "employeeActivities", that needs some value, when I make a new Object. But at this point, there is no EmployeeActivity-Object that i could use. How do I manage this?

Thanks a lot & have nice day! NicerDicer

NicerDicer
  • 29
  • 5

1 Answers1

0

I meanwhile found the solution. The problem was, that I tried to use the AllArgsConstructor that has been generated via lombok. The AllArgsConstructor expects of course all attributes that I declared in the entitties. The solution is to use setters (in my case auto-generated by the lombok @Data annotation) and to not set the id and employeeActivities from project & employee.

(Alternatively you can of course write your own constructor.)

@Override
public void run(String... args) throws Exception {
    Project project_1 = new Project();
    project_1.setName("BERLIN_AIRPORT");
    project_1.setStartDate("2006-05-01");
    project_1.setEndDate("2020-10-31");
    project_1.setStatus(Status.COMPLETED);
    projectRepository.save(project_1);

    Employee employee_1 = new Employee();
    employee_1.setFirstName("Jim");
    employee_1.setLastName("Beam");
    employee_1.setRole("Architect");
    employee_1.setHoursPerWeek(BigDecimal.valueOf(40d));
    employeeRepository.save(employee_1);

    EmployeeActivity employeeActivity = new EmployeeActivity();
    employeeActivity.setProject(project_1);
    employeeActivity.setEmployee(employee_1);
    employeeActivity.setStartDate("2019-05-01");
    employeeActivity.setEndDate("2022-12-12");
    employeeActivityRepository.save(employeeActivity);
}
NicerDicer
  • 29
  • 5