Using Hibernate, I have created two entities - Employee and EmployeeDetails. Since EmployeeDetails cannot exist without a corresponding entry in Employee, I figured I don't need an extra ID for EmployeeDetails, but could instead use the ID of the Employee entity. Here is how I have implemented this idea:
Employee-Entity:
@Entity
@Table(name = "employees")
@Data
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id")
private Long id;
@Column(name = "first_name", nullable = false)
private String firstName;
@Column(name = "last_name", nullable = false)
private String lastName;
@OneToOne(cascade = CascadeType.ALL)
EmployeeDetails employeeDetails;
}
Employee-Details-Entity:
@Entity
@Table(name = "employee_details")
@Data
public class EmployeeDetails {
@Id
private Long id;
@Column(name = "address")
private String address;
@Column(name = "e_mail", nullable = false)
private String eMail;
@Column(name = "phone")
private String phone;
@MapsId
@OneToOne(mappedBy = "employeeDetails", cascade = CascadeType.ALL)
@JoinColumn(name = "employee_id")
private Employee employee;
}
By adding the @MapsId
annotation to the employee-variable inside EmployeeDetails, I should be assigning the primary key of the Employee-entity to the Id-column of EmployeeDetails.
In a second step, I have written some data into both of my tables.
employee table in MySQL database:
employee_id first_name last_name employee_details_employee_id
1 John Smith null
2 Jennifer Adams null
The last column was somehow generated by Hibernate. I don't understand why. It appears to be some column for identification, but I don't need it.
employee_details table in MySQL database:
employee_id address e_mail phone
1 null [email protected] null
2 null [email protected] null
I have only assigned an e-mail to the employees. Surprisingly, there is no employee-entry in this database table. I don't really need it anyways, but I was expecting it. So yeah, I think I am doing something terribly wrong and would really appreciate some help.
CodePudding user response:
@MapId
is not a popular solution in work with Hibernate.
Maybe in your case, @Embeddable
will be a better option?
If I understand correctly, EmployeeDetails
cannot exist without correlated Employee
. So, EmployeeDetails
could be a field in Employee
as an embeddable field:
@Entity
@Table(name = "employees")
@Data
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id")
private Long id;
@Column(name = "first_name", nullable = false)
private String firstName;
@Column(name = "last_name", nullable = false)
private String lastName;
@Embedded
EmployeeDetails employeeDetails;
}
Then EmployeeDetails
doesn't need ID and relation with the employee:
@Embeddable
public class EmployeeDetails {
@Column(name = "address")
private String address;
@Column(name = "e_mail", nullable = false)
private String eMail;
@Column(name = "phone")
private String phone;
}
As you can see, now in the database it's only one table employees
, but in our hibernate model, we have two separated objects. Probably you don't need EmployeeDetails
without Employee
entity, so there is more efficient construction.
If you really need a separated table for EmployeeDetails
with relation to Employee
I recommend creating standard one-to-one mapping instead of @MapId
construction.
CodePudding user response:
Change mappedBy side, here useful links
https://vladmihalcea.com/change-one-to-one-primary-key-column-jpa-hibernate/ https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/ https://javabydeveloper.com/one-one-bidirectional-association/
@Entity
@Table(name = "employees")
@Data
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id")
private Long id;
@Column(name = "first_name", nullable = false)
private String firstName;
@Column(name = "last_name", nullable = false)
private String lastName;
@OneToOne(mappedBy = "employee", cascade = CascadeType.ALL)
EmployeeDetails employeeDetails;
}
Entity
@Table(name = "employee_details")
@Data
public class EmployeeDetails {
@Id
private Long id;
@Column(name = "address")
private String address;
@Column(name = "e_mail", nullable = false)
private String eMail;
@Column(name = "phone")
private String phone;
@MapsId
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "employee_id")
private Employee employee;
}