Hello there:
the application I'm working on requires two entities with a one-to-one relationship, with one end of the relationship being polymorphic.  For the sake of illustration, I'll use a variation of an example from the "Java Persistence with Hibernate" book.  Consider the entities from  section "7.3.1 Polymorphic many-to-one associations":
Code:
+-----------+    default    +------------------+
|   User    | ------------> |  BillingDetails  |
+-----------+               |   < abstract >   |
                            +------------------+
                                     ^
                                     |
                          +-----------------------+
                          |                       |
                          |                       |
                 +-----------------+       +-------------------+        
                 |  CreditCard     |       |    BankAccount    |
                 +_________________+       +___________________+ 
Here, "default" is a one-to-one relationship that may vary over time: a User may start with a CreditCard instance as its default BillingDetails, but later this can be changed so that a BankAccount instance becomes the default.  At any one time, only one concrete BillingDetails subclass should be associated with the User.
My database schema is using a single table per-class-hierarchy strategy along the lines of:
Code:
+-------------------------+             +--------------------------+      
|          USER           |             |      BILLING_DETAILS     |
|-------------------------|             |--------------------------|
| FK : billing_details_id | ----------> | PK : billing_details_id  |
|-------------------------|             |--------------------------|
| PK : user_id            |             | billing_type             |       
+-------------------------+             +--------------------------+
where "billing_type" is the discriminator column identifying whether the record corresponds to a CreditCard or BankAccount instance.
In summary, at any one time, there should be exactly one record in BILLING_DETAILS table for each record in USER.
I'm using the following xml Hibernate mapping files:
User.hbm.xml:
=========
Code:
<hibernate-mapping package="com.foo.domain">
   <class name="User" table="USER">
      <id name="id" column="user_id">
         <generator class="native" />
      </id>
      <!-- user properties go here -->
      
      <many-to-one name="billingDetails" class="BillingDetails"
                      column="billing_details_id" cascade="save-update" 
                      unique="true" lazy="false" />
   </class>
</hibernate-mapping>
BillingDetails.hbm.xml:
==============
Code:
<hibernate-mapping package="com.foo.domain">
   <class name="BillingDetails" table="BILLING_DETAILS">
      <id name="id" column="billing_details_id">
         <generator class="native" />
      </id>
      
      <discriminator column="billing_type" />
      <!-- common billing details properties go here -->
      <subclass name="CreditCard" discriminator-value="CC">
         <!-- credit card specific properties go here -->
      </subclass>
      <subclass name="BankAccount" discriminator-value="BA">
         <!-- bank account  specific properties go here -->
      </subclass>
   </class>
</hibernate-mapping>
Creation works as expected, but I'm having problems with updates.  Consider the following scenario: a User instance with a BankAccount exists in the database and the application receives an update request to replace the User's BankAccount with a CreditCard instance:
Code:
// Session is created and new transaction is opened
// Get the User from the db: user has BankAccount instance attached
User user = getSession().get( User.class, 55 );
// creditCard is a detached instance of type CreditCard passed in as a parameter:
// merge it with the the loaded billing details attached to the user
BillingDetails newDetails = (BillingDetails)getSession().merge( creditCard );
// Update user with new billing details (credit card)
user.setBillingDetails( newDetails );
// Persist changes to user
getSession().saveOrUpdate( user );
// Transaction is committed and session closed
For simplicity' sake, I extracted the steps above from various classes (SessionFilter, UserService, UserDao), just to illustrate the flow.
Before the update, the data looks like:
user: 
----
user_id = 55
billing_details_id = 56
billing_details:
--------------- 
billing_details_id = 56
billing_type = BA
After the update, I get:
user: 
----
user_id = 55
billing_details_id = 57
billing_details:
--------------- 
billing_details_id = 56
billing_type = BA
billing_details_id = 57
billing_type = CC
Notice that the old billing_details record (id=56) still exists in the db and a new billing_details record (id=57) was created and associated with the user.
Ideally, what I want is to update the existing billing_details record with the new information, so that the db ends up like:
user: 
----
user_id = 55
billing_details_id = 56
billing_details:
--------------- 
billing_details_id = 56
billing_type = CC
I am clearly doing something wrong, so I'd be happy to hear any suggestions/recommendations that anyone can give.
Let me know if I've left out any relevant information that may help clarify things.
Thank you in advance for any help.
Regards