3

Background: I'm implementing persistence for the following classes:

  • class Person

  • abstract class ContactInfo

    • Email extends ContactInfo
    • SnailMail extends ContactInfo

Each Person has a reference to a ContactInfo object. (And a ContactInfo object can be shared among several Person.)

In my user interface I need to let the user edit the contact information object and possibly replace an email address with a snail mail address. (If the contact info object which is to be replaced is shared among several persons, all those persons should have their contact info updated.)

As I understand it however, Hibernate refuses to update the discriminator column, so simply creating a new SnailMail object, giving it the primary key value of the Email object which is to be replaced, and saving it doesn't work.

Question: What is the best way to allow the user to change a ContactInfo object from Email to SnailMail?

(The objects are "short lived". It's part of a web-app and all objects are re-read through HQL upon each request, so there's not really any detached objects to worry about.)

My thoughts so far: I realize that I could delete the old object, insert the new one. If this is the preferred approach, should I (A) try to reuse the old primary key value (in which case I need to use assigned generator) or (B) let the back-end generate a fresh ID for the new object, and update the persons contact-references to point to the new object?

If (B) is the way to go, can I do the update of the references using some HQL-statement, or should I load / update / save all the affected person-objects "manually"?

Nadeem_MK
  • 7,533
  • 7
  • 50
  • 61
aioobe
  • 413,195
  • 112
  • 811
  • 826

1 Answers1

0

I think it's unlikely that you can update it with a completely new instance of a different class. After all, you've created a new entity and so it's not really an update.

Are you sure Person doesn't need multiple ContactInfo(s)? If the relation was many2many, you could manage it as such and maybe you are already managing similar cases. The web interface would explicitly show 'address 1, 2, ...', each rendered based on its specific type, each with '-' button and a '+' button at the end. This will make it clear that they have to remove/add a contact info if they want to change its type.

A similar approach is to delete/re-create a contact info, only if the user has changed its type (probably you already have to render a new web form). I don't think you can avoid to update links to other Person(s) in such a case. I would do it by making the relation bi-directional, i.e. introducing both Person.getContactInfo() an ContactInfo.getPersons(). I would manage bi-directionality inside add()/delete() methods (i.e., addContactInfo( ContactInfo c) should call c.addPerson ( this ) and vice-versa, see here) and Hibernate should be able to update the foreign keys automatically.

zakmck
  • 2,715
  • 1
  • 37
  • 53