Home > database >  How to save spring entities solely using the foreign key of an associated object
How to save spring entities solely using the foreign key of an associated object

Time:10-02

I have two spring entities, job and employer, which have a bidirectional association.

Job Entity

@Entity
@Table(name = "job")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Job {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "job_id", nullable = false)
    private Integer id;

    @Column(name = "title", nullable = false)
    private String title;

    @ManyToOne(optional = false)
    @JoinColumn(name = "employer_employer_id", nullable = false)
    @JsonBackReference
    private Employer employer;
}

Employer Entity

@Entity
@Table(name = "employer")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Employer {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "employer_id", nullable = false)
    private Integer employerId;

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

    //Mapped by indicates the inverse side of the relationship.
    @OneToMany(mappedBy = "employer", orphanRemoval = true)
    @JsonManagedReference
    private List<Job> jobs = new ArrayList<>();

}

I also have two simple CRUD repositories

Let's say that I have an existing employer object saved in the database. In my jobs service, I want to have a method that creates a new job. My question is, what is the correct Spring boot way to save a new job entry in the database where the employee id foreign key relates back to that existing job in the database.

Here is my first attempt, and it works, however it doesn't seem very efficient. Why should I have to retrieve the entire employer object from the database, when I really just want to specify the employer ID of the job I am trying to save? Is there a way I can avoid making this extra database call, and when we are saving the job to the database, just easily specify an existing employer ID on that new job we are saving to the database? Or is it Spring best practice to have to save the entire employee object here, even if it already exists?

 Employer e = employerRepository.findById(0).orElseThrow(IllegalArgumentException::new);
 job1.setEmployer(e);
 jobRepository.save(job1);

CodePudding user response:

Best way is use getOne so you don't even have to fetch the empoyer

Employer e = employerRepository.getOne(id);
 job1.setEmployer(e);
 jobRepository.save(job1);

If employer does t exist an exception will be thrown when you save job.

getOne is deprecated in later versions of jpa so use this instead

JpaRepository#getReferenceById(ID)

CodePudding user response:

Good/progressive question:

Why should I have to retrieve the entire employer object from the database, when I really just want to specify the employer ID of the job I am trying to save?

We don't have to! We can:

Employer empler =
entityManager.getRefernce(Employer.class, 0L); 

Resp. with :

JPARepository.getReferenceByIdID(...);

Regarding "how to do it best" (and in which queries it results), i can additionally very recommend: https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/ (Where Employer is analogous to Post and Job analogous to PostComment;)

  • Related