0

I have been playing around with JPA and came across this scenario and wanted to know how to solve this.

I have 2 tables namely Company and Employee. So here an employee can work for only 1 company, therefore @OneToOne uni-directional mapping is done in Employee class. And the company details in the Company table would already exist.

So when I try to insert a record into Employee table, I even create a reference to the company, add it to the Employee class and save it using my EmployeeRepository's save method. Since the company_id would already exist in Company table, it should just refer it instead of creating a new company. But this is not happening. I get an exception saying company object is still in the transient state. I can solve this by adding CascadeType.All but I don't need to insert the company rather I have to just link the company to the employee.

Here are the code snippets.

Employee Class

@Entity
@Table(name = "employee")
@Setter
@Getter
public class Employee
{
    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "employee_id")
    private Integer employeeId;

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

    @OneToOne
    @JoinColumn(name = "company_id")
    private Company company;

}

Company class

@Entity
@Table(name = "company")
@Setter
@Getter
public class Company
{
    @Id
    @GeneratedValue
    @Column(name = "company_id")
    private Long id;

    @Column(name = "company_name")
    private String companyName;
}

Company Table

company_id  company_name
1           Dell
2           Apple
3           Microsoft

Here is how I am creating the Employee object

Employee emp = new Employee();
emp.setEmployeeId(10);
emp.setEmployeeName("Michael");

Company company = new Company();
company.setId(1);
emp.setCompany(company);

employeeRepository.save(emp);

Please, someone, let me know how to link the company class to an employee class rather than saving one more company.

Rajath
  • 21
  • 3

2 Answers2

1

The best solution for me is to lazy load your company with a proxy. To do it with Spring Data JPA, you need to make your company repository extends JpaRepository. That give you access to the method getReferenceById :

Employee emp = new Employee();
emp.setEmployeeId(10);
emp.setEmployeeName("Michael");
emp.setCompany(companyRepository.getReferenceById(1))

employeeRepository.save(emp);

If there is no company for the given id, an EntityNotFoundException is throw.

With a proxy, you avoid the request to the database in most case because Hibernate use its cache for check the existence of the company. But if my memory serves me correctly, Hibernate gonna make a request to the database at each call to a getter of the proxy, except for getId(). So, in your case it's a good solution, but don't use it all the time.

Vivien
  • 57
  • 8
0

Assuming the Company may have more than one Employee the relation is a ManyToOne, not a OneToOne.

If you want to reference an existing entity, load it instead of creating a new one:

Employee emp = new Employee();
// ...

emp.setCompany(companyRepository.findById(1));

employeeRepository.save(emp);
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348