-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: Can we update the discriminator column in Hibernate
PostPosted: Fri Aug 19, 2005 10:15 am 
Regular
Regular

Joined: Wed Jul 27, 2005 2:33 am
Posts: 118
I have the following case:

Code:
<class
    name="xyz"
    table="XYZ"
    discriminator-value="-1"
>
    <composite-id name="id" class="xyzId">
        <key-property
            name="id"
            column="xyzID"
           
        >
        </key-property>
        <key-property
            name="versionId"
            column="vID"
           
        >
        </key-property>
       
    </composite-id>   
   
    [b]<discriminator column="Type_Cd" type="short"/>[/b]
[b]
<timestamp
           name="revisionDate"
           column="UPDATE_DTTM"
    />[/b]
.....
<property
        name="processingTypeCd"
        type="short"
        column="Type_Cd"
        not-null="true"
        insert="false"
        update="false"
    >
    </property>

<!-- Mapping for subclasses -->
       <subclass name="xyz123"  discriminator-value="1">
         
      </subclass>
      
      <subclass name="xyz456"  discriminator-value="2">
         
      </subclass>
...


Now suppose i retrive a xyz123 object(discriminator value =1) from database and create a new xyz456 object(discriminator value =2). I assign the 'id' and the 'revisionDate' from xyz123 object to xyz456 object.

By doing this, what i achieve is, i instruct hibernate to fire an update statement on the table. Everything works fine, except that even if i change the discriminator value it DOES NOT get reflected in the table.
Also, the update query so generated never has this discriminator column in its update statement.

So does this mean that we are never allowed to update the discriminator column?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 19, 2005 11:01 am 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
I'm pretty sure you can't do this. Think about what you are trying to do from an OO standpoint. Changing the discriminator is trying to change an object's class (certainly not something you should want to do from an OO standpoint). You should delete the old object and create a new one.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2005 1:57 am 
Regular
Regular

Joined: Wed Jul 27, 2005 2:33 am
Posts: 118
Hi,
Thank you for the reply. Ya you are right, i will have to delete the first instance and create a new one of different type. Thank you.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 15, 2005 8:26 am 
Beginner
Beginner

Joined: Fri Apr 09, 2004 12:47 pm
Posts: 36
I'm facing the same problem, but in my problem domain it makes sense to change the class, it's a requirement.

I have multiple objects referring an "activity" a1 whose type is ActivityOne, but at some time the user decides he needs to turn a1 into an ActivityTwo class. He needs to to that in every place it's using the activity, and it's a mess to change that in every users collection. Changing the discriminator is much easier.
Are you sure there is no way at all to perform this kind of change?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 15, 2005 10:11 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
Use "discriminator" as usual property in domain model. If you need to change "discriminator" then it meens there is no inheritance in domain model, drop it.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 15, 2005 10:23 am 
Beginner
Beginner

Joined: Fri Apr 09, 2004 12:47 pm
Posts: 36
baliukas wrote:
Use "discriminator" as usual property in domain model. If you need to change "discriminator" then it meens there is no inheritance in domain model, drop it.


Impossible, every class has distinct behaviour and extra fields compared
to the abstract base class.
Look, when a user asks to change the type of an "activity" in my user interface, I just keep the common fields between the two subclasses, and ask the user to fill in the missing fields before finishing the conversion in the user interface.

Anyway, I've changed the code to "update" the database with the changed class, flush the session, and then perform a discriminator change by hand using a query. Works fine.
It seems to me that you've decided it does not make sense to change an object class and thus do not support it, but it would be tecnically feasible.

I've also asked my colleagues, one has already stumped in this problem and found another workaround (it was a simpler case), but he also needed to change the class of a persistent object, that is, it was the logical thing to do.
Mine or his workaround are just tricks, they don't match the logic of what we're doing...


Top
 Profile  
 
 Post subject: Re: Can we update the discriminator column in Hibernate
PostPosted: Wed Mar 27, 2013 1:10 am 
Newbie

Joined: Mon Mar 26, 2007 12:57 pm
Posts: 3
Location: Canberra, Australia
You can do this using a subclassed decorator pattern:

Code:
class HibernateTable {
   int type;
   int column_relevant_to_all_subclasses;
   String column_relevant_to_type1;
   Date column_relevant_to_type2;

   Type1 asType1() {
      if(type != 1) throw new IllegaleStateException();
      return new Type1(this);
   }

   Type2 asType2() {
      if(type != 2) throw new IllegaleStateException();
      return new Type2(this);
   }

   MyClass asMyClass() {
      switch(type) { case 1: return asType1(); case 2: return asType2(); }
   }
}

abstract class MyClass {
  final HibernateTable t;
  MyClass(HibernateTable t) { this.t = t;}
  abstract void doThing();

  int getColumRelvantToAllSubclasses() { return t.getColumnRelevantToAllSubclasses();}
}

class Type1 {
  Type1(HibernateTable t) { super(t); }
  void behaviour_relvant_to_type1() {}
  void doThing() { }
  String getColumRelevantToType1() {
    return t.column_relevant_to_type1;
  }
}

class Type2 {
  Type2(HibernateTable t) { super(t); }
  void behaviour_relvant_to_type2() {}
  void doThing() { }
  Date getColumRelevantToType2() {
    return t.column_relevant_to_type2;
  }
}

HibernateTable tt;

tt.asType1().behaviour_relevant_to_type1();
tt.asType2().behaviour_relevant_to_type2();
tt.asMyClass().doThing();



Add some code to automatically create the decorator object onLoad and switch it when you update type if you want to not be creating a new one every time you call myBean.asType1()


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.