Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hibernate doesn't update discriminator column when I update with another object

I have used a "class per hierarchy strategy" for mapping the following class hierarchy in Hibernate.

I have Item as an abstract class. The followings as concrete ones: Book Journal DVD CD

My mapping works perfect for saving and loading but it doesn't work correctly on updating an item with a different class. I'm using discriminators for each of the above classes.

my item.hbm.xml is like:

<!-- language: lang-xml -->
<hibernate-mapping>
    <class name="my.hibernate.items.Item" discriminator-value="item"
        table="testitem" catalog="efeu">
        <id name="id" type="java.lang.Long">
            <column name="id" />
            <generator class="native" />
        </id>
        <discriminator column="item_type" type="string" length="8" />
        <subclass name="my.hibernate.items.DVD" discriminator-value="DVD">
            <property name="duration" type="java.lang.Integer" column="duration" />
            <property name="trackNumber" type="java.lang.Integer"
                column="trackNumber" />
        </subclass>
        <subclass name="my.hibernate.items.Journal"
            discriminator-value="Journal">
            <property name="serialNumber" type="java.lang.Integer"
                column="serial_number" />
        </subclass>
    </class>
</hibernate-mapping>

and for updating I use this method:

<!-- language: lang-java -->
public static void updateItem(Item newItem){
    Session session = HibernateSessionFactory.getSession();
    Transaction tx = session.beginTransaction();

    session.update(newItem);// I tried merge too. it created a new row

    tx.commit();
    session.close();
}

There is no difference which class instance I send to updateItem method. All the fields are updated except the discriminator so if it is a book remains a book and I can't convert it to CD, DVD or journal invoking the above method with an object of that kind as parameter.

I think it is clear what I am doing. I assum that I know that the row with id=111 in the database table is a Book object. So I do the following:

<!-- language: lang-java -->
Item cd = new CD();
cd.setId(111);
cd.setXXXProperties()
Item.updateItem(cd);

it is clear that cd is transient before invoking the method and I haven't loaded the row with id=111 before that.

What should I do to make Hibernate change the discriminator column on invoking the update method?

like image 791
Johnny Avatar asked Jan 30 '26 11:01

Johnny


1 Answers

There is no way how to update a discriminator value. What you are experiencing is correct. Once object is created (as a CD or as a Book) it won't change its type.

Read more here: 5.1.6.1.1. Discriminator

<discriminator
        column="discriminator_column"                      (1)
        type="discriminator_type"                          (2)
        force="true|false"                                 (3)
        insert="true|false"                                (4)
        formula="arbitrary sql expression"                 (5)
/>

There is no update operation for discriminator.

like image 170
Radim Köhler Avatar answered Feb 02 '26 03:02

Radim Köhler



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!