farzad wrote:
What is the mapping for the one that doesn't work?
OK, here it is (sorry for that late response, I was lying ill in bed last days)
first, this is the mapping which does not work as I expect it:
(a Contact may be the owning parent of several BankAccount objects:
Code:
class BankAccount {
....
@ManyToOne
@JoinColumn(name = "CONTACT_ID", nullable=false, updatable=false, insertable=false) // Hibernate book, p. 294!! @org.hibernate.annotations.ForeignKey(name="FK_CONTACT_BANKACCNT_ID")
private Contact contact;
class Contact {
...
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
@JoinColumn(name = "CONTACT_ID", nullable = false)
@org.hibernate.annotations.IndexColumn(name="BANK_LISTPOS")
@org.hibernate.annotations.Cascade(value=org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private List<BankAccount> bankAccounts = new ArrayList<BankAccount>();
And here is the relation, where DELETE_ORPHAN does what i expected it to do:
(an Institution may have several PersonContacts )
Code:
class PersonContact {
...
@ManyToOne(optional = true) //, cascade=CascadeType.ALL)
@JoinTable(name = "PERSON_INST_CONTACT",
joinColumns = { @JoinColumn(name = "PERSON_ID") },
inverseJoinColumns = { @JoinColumn(name = "CONTACT_ID") })
@org.hibernate.annotations.ForeignKey(name="FK_PERSON_INSTITUT_ID")
private InstitutionContact institution;
class InstitutionContact {
...
@OneToMany(mappedBy="institution",
cascade = {CascadeType.MERGE,CascadeType.REMOVE}, // cascade = {CascadeType.ALL},http://www.junlu.com/msg/390434.html
fetch = FetchType.EAGER)
// we can savely let Hibernate do a cascade orphan delete:
@org.hibernate.annotations.Cascade(value=org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private Set<PersonContact> persons = new HashSet<PersonContact>();
To repeat my situation: Firstly, I work with detached objects. A Java desktop client (actually a EJB client) requests the business objects from server (entities) and acts on them (may create new ones, delete others). That is, the set of PersonContacts is displayed in a JTable, and the user may delete a row from this table. The same applies to the BankAccounts. So, when the user presses OK (=save), the object graph is passed back to the EJB server, where an EntityManager just calls merge() on the root object. The rest is expected to be done by Hibernate.
To repeat: automatic detection of the deletion of a BankAccount works as expected: Hibernate generates the SQL for it; but this is not the case for the PersonContact.
I cannot see why Hibernate acts differently on the slightly different associations. Maybe it is the @JoinTable I use on that association (I have some reasons for it).
So, do you have an idea what to do? I don't think that it should be the task of my EJB to track changes on the persistent objects themself. If it was, why should I use an ORM at all -:) ?
Carlo