I have 2 tables. One is called Employee, and the other is called Phones, and an employee can have multiple Phones.
Employee Class:
@Entity
@Table(name = "employee")
public class Employee {
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
private Integer id;
@Column(name = "name", unique = true, nullable = false, length = 25)
private String name;
@OneToMany(mappedBy="owner", fetch= FetchType.EAGER, orphanRemoval=true, cascade={CascadeType.ALL})
private List<Phone> phones;
Phone class:
@Entity
@Table(name = "phone")
public class Phone {
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
private long id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "employee_id")
private Employee owner;
@Column(name = "phone_type", nullable = false, length = 25)
private String phoneType;
@Column(name = "phone_number", nullable = false, length = 25)
private String phoneNumber;
Suppose I want to add a phone to an existing employee. I am doing this:
Phone phone = new Phone();
phone.setOwner(employee);
phone.setPhoneNumber("999-555-0001");
phone.setPhoneType("home");
employee.getPhones().add(phone);
dao.merge(employee); // Is it possible to get this to both persist new phones and update existing phones that were changed?
I'm not sure how to merge new phones in, given that some of the phones in the phoneSet have already been persisted. Must I persist each phone manually? An example would be greatly appreciated. I looked into cascading but I can't seem to get it to work. The error I'm receiving is: java.lang.IllegalStateException: An entity copy was already assigned to a different entity.
I think the issue may be in your join column annotation in the Phone class. You are specifying a join column of employee_id
yet in the Employee class the @Column
annotation for the id field is mapped to the column id
.
Try changing/synchronizing the join columns:
@ManyToOne(fetch = FetchType.EAGER, targetEntity=your.package.here.Employee.class)
@JoinColumn(name = "id")
private Employee owner;
or
Employee.java
@Id
@Column(name = "employee_id", unique = true, nullable = false)
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
private Integer id;
Phone.java
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "employee_id", targetEntity=your.package.here.Employee.class)
private Employee owner;