I have Employee
(parent) and Emp_Contacts
(child). Only Employee
class has unidirectional mapping.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Size(min=3, max=50)
@Column(name = "NAME", nullable = false)
private String name;
...
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "emp_id")
private Set<Emp_Contacts> contacts;
...getters and setters...
My Emp_Contacts
is as follows:
@Entity
@Table(name = "Emp_Contacts")
public class Emp_Contacts implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int emp_contact_id;
@NotNull
@Column(name = "emp_id")
private long emp_id;
....
DB table has not null FK constraint for emp_contacts
table on emp_id
.
persist(employee)
will persists employee and corresponding emp_contacts.With FK constraint I get below error:
MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
I searched on internet and found this link https://forum.hibernate.org/viewtopic.php?f=1&t=995514
But if I put nullable in Employee
:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "emp_id", nullable = false)
private Set<Emp_Contacts> contacts
my server does not even start, I get below error:
Repeated column in mapping for entity: com.cynosure.model.Emp_Contacts
column: emp_id (should be mapped with insert="false" update="false")
What am I doing wrong ?
Employee
is the association owning side (because it's the only side). That way foreign key is always updated separately from inserting the associated Emp_Contacts
instances, so it must be nullable.
The recommended solution is to make the association bidirectional and make the many side the owner of the association:
public class Employee {
@OneToMany(mappedBy = "employee")
private Set<Emp_Contacts> contacts;
}
public class Emp_Contacts {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "emp_id", nullable = false)
private Employee employee;
}
This way the foreign key can be not-nullable and you avoid the costs of an extra statement to update the foreign key because the foreign key value is set when inserting Emp_Contacts
.
Also, you will always have the associated employee id in the Emp_Contacts
instance (what seems to be your intention). You don't have to load the employee from the database in order to access its id because the association can be declared lazy (as in the example above) and Hibernate will generate a proxy containing only the id. See this answer for more information.
Another benefit is that you can navigate the association from both sides when needed (useful also in HQL/JPQL queries).
If you nevertheless want to use your original solution (unidirectional association with only plain foreign key value on the many side), then make the join column nullable and make the emp_id
property insertable = false, updatable = false
, because Hibernate will automatically update the mapped foreign key column when maintaining the association on the Employee
side:
@Column(name = "emp_id, insertable = false, updatable = false")
private long emp_id;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With