I have a bidirectional one-to-many relationship with the following entity classes:
0 or 1 client <-> 0 or more product orders
When persis
@SputNick ,I solved it by the steps described below.I am going to use your code snippet to demonstrate what I did,
You have Client entity -@OneToMany and ProductOrder entity -@ManyToOne .I will use
// Called when pressing "save" on the "edit..."
public void edit(T entity) {
getEntityManager().merge(entity);}
for persistence as it can give me flexibility to save as well as update.
To create Client and corresponding Product orders use
client.set..(some property to be saved);
productOrder.set..(some property to be saved);
//Set productOrder for the client
List<ProductOrder> order = new ArrayList<>();
client.setOrders(order);
//Note that this expects a list to be passed
//set client for the productOrder
productOrder.setClient(productOrder);
.edit(client) or .edit(productOrder)
Note that either way will be able to update both entity tables with your changes.
Though late,hope it will help someone
Ensure you are setting both sides of the relationship, you cannot just add the order to the client, you also need to set the client of the order. Also you need to merge both objects that you have changed. If you just merge the client, then the order's client will not be merged (although your cascade you cause it to be merged).
persist does not work, as persist requires that the object being persisted be correct for the persistence context, i.e. not reference detached objects, it must reference managed objects.
Your issue comes from you detaching of the objects. If you did not detach the objects, you would not have the same issues. Normally in JPA you will create an EntityManager, find/query your objects, edit/persist them, call commit. No merging is required.
Use @Joincolumn annotation in your ProductOrder entity, please see below.
@Entity
public class ProductOrder implements Serializable, ChildEntity {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne // owning side
@JoinColumn(name = "PRODUCTORDER_ID", referencedColumnName = "ID")
//write your database column names into name and referencedColumnName attributes.
private Client client;
// other fields, getters and setters
}
Hi i had the same problem today, i ask to the openJPA mailing list with this email:
Hi. I have a problem with insert and updating a reference in the same entity.
Im trying to insert a new object (Exam) that has a reference to another object (Person) and at the same time i want to update an attribute (birthDate) of the Person object. The update never happens although i set CascadeType to ALL. The only way this works is doing a persist and after that a merge operation. Is this normal? Do i have to change something??
I dont like the idea of a "manual update" using merge in the Person object because i don't know how many objects (child object of Exam) the user want to update.
Entities:
public class Exam{
@ManyToOne(cascade= CascadeType.ALL)
@JoinColumn(name = "person_id")
public Person person;
......
}
public class Person{
private Date birthDate;
@OneToMany(mappedBy = "person")
private List<Exam> exams
.......
}
public class SomeClass{
public void someMethod(){
exam = new Exam()
person.setBirthDate(new Date());
exam.setPerson(person);
someEJB.saveExam(exam);
}
}
public class someEJB(){
public void saveExam(Exam exam){
ejbContext.getUserTransaction().begin();
em.persist(exam);
//THIS WORKS
em.merge(exam.getPerson());
ejbContext.getUserTransaction().commit();
}
}
Do i have to use the MERGE method for every child object?
And the answer was this:
It looks like your problem is that the Exam is new, yet the Person is existing and the existing Entity gets ignored when cascading the persist operation. I believe this is working as expected.
As long as your relationships are set to CascadeType.ALL, you could always change your em.persist(exam); to em.merge(exam);. That would take care of persisting the new exam, and it would also cascade the merge call to the person.
Thanks, Rick
I hope this can help you.