Search code examples
javaspring-data-jpaormdto

One-Many Relationship in Jpa


I want to get data from my entity with 1-M relationships. Users have an entity for cv information.With JpaRepo, Cv class :

@Entity
@Table(name = "cvs")
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "educations", "works", "langueges", "technologies"})
public class CV {

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

    //ToDo : Employee bilgilerinin görünmesi problemi giderilecek.
    @OneToOne
    @JoinColumn(name = "employee_id")
    private Employee employee;

    @OneToMany(mappedBy = "cv", cascade = CascadeType.ALL, orphanRemoval = true)
    List<Education> educations;

    @OneToMany(mappedBy = "cv", cascade = CascadeType.ALL, orphanRemoval = true)
    List<Work> works;

    @OneToMany(mappedBy = "cv", cascade = CascadeType.ALL, orphanRemoval = true)
    List<Languege> langueges;

    @OneToMany(mappedBy = "cv", cascade = CascadeType.ALL, orphanRemoval = true)
    List<Technology> technologies;

    @Column(name = "github")
    private String github;

    @Column(name = "linkedin")
    private String linkedin;

    @NotNull
    @NotBlank
    @Column(name = "cover_letter")
    private String coverLetter;

    @Column(name = "photo")
    private String photo;
    
}

This is Education class (work, languege, technology classes same):

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "cv_educations")
public class Education {

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

    @NotNull
    @NotBlank
    @Column(name = "school_name")
    private String schoolName;

    @NotNull
    @NotBlank
    @Column(name = "department")
    private String department;

    @NotNull
    @NotBlank
    @PastOrPresent
    @Column(name = "starting_date")
    @DateTimeFormat(pattern = "yyyy-mm-dd")
    private LocalDate startingDate;

    @NotBlank
    @Column(name = "graduation_date")
    @DateTimeFormat(pattern = "yyyy-mm-dd")
    private LocalDate graduationDate;

    @ManyToOne
    @JoinColumn(name = "cv_id")
    private CV cv;
}

I tried to build the following structure with jpa, but the constructer takes list parameter. I got an error because I couldn't write it with jpql

public interface CvRepository extends JpaRepository<CV, Integer> {

        @Query("select new com.demo.humanresourcesmanagementsystem.Entities.concretes.CV" +
                "(employee.firstName, employee.lastName, cv.github, cv.linkedin, cv.coverLetter," +
                "educations, works, langueges, technologies)" +
                "from CV cv inner join cv.employee employee inner join cv.educations educations " +
                "inner join cv.works works inner join cv.langueges langueges " +
                "inner join cv.technologies technologies where cv.employee.id =:employeeId")
        CV findByCv(int employeeId);
    }

I'd like to read about the educations, works, langueges and technologies in this entity. This means that there will be one cv as output, but there may be more than one education object within the cv (such as primary school, high school), and the incoming data will be in the following format, for example:

"firstName": "X",
"lastName" : "X",
"educations" : [
           "education1" {
                  "school" : "x", 
                  "department" : "x" ...}, 
           "education2" {
                  "school" : "x", 
                  "department" : "x"...}
"works" : [
    "work1" {
           "workplace" : "x", 
           "job" : "x" ...
          }
       ]
"github" : "x",
"linkedin" : "x"

How do i set up this structure with the jpa repository? What kind of dto should I write if I'm gonna use it? Thanks.

UPDATE

When i use spring jpa derivered query (findByEmployeeId) i receive data with this format :

{
  "success": true,
  "message": "string",
  "data": {
    "id": 0,
    "employee": {
      "id": 0,
      "email": "string",
      "password": "string",
      "firstName": "string",
      "lastName": "string",
      "nationalIdentity": "string",
      "yearOfBirth": 0
    },
    "github": "string",
    "linkedin": "string",
    "coverLetter": "string",
    "photo": "string"
  }
}

So i cant receive data for education, work, languege and technology.


Solution

  • It seems you're trying to retrieve a CV by its employer.id. In that case, you can really just use the JPA query method containing keywords. In this case it would look like:

    CV findByEmployeeId(int employeeId);

    This should return the complete CV object as you would expect.

    See here for more details on JPA query method keywords.