-->
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.  [ 2 posts ] 
Author Message
 Post subject: Problems with a Set of abstract base class derivitives.
PostPosted: Wed Jan 10, 2007 3:58 pm 
Newbie

Joined: Wed Jan 10, 2007 3:07 pm
Posts: 8
I'm using Hibernate 3.1 going against an Oracle 9 DB.

I have a class Order that contains a Set of AbstractFoos, and a String fooType. AbstractFoo has 3 subclasses (FooA, FooB, and FooC), which are each mapped to a different table. The Set will always be homogenous in that it will always contain instances of a single subclass. fooType indicates which type is stored in the Set.

The mapping file looks like:

Code:
<hibernate-mapping>
<class     
       name="c.e.e.t.view.order.bo.Order"
       table="ORDER_MASTER"
       lazy="false">
    <property
              name="fooType"
              type="java.lang.String"
              column="FOO_TYPE"
              length="4"/>
    <set     
           name="fooThings"
           lazy="false"
           inverse="true"
           cascade="all-delete-orphan">
       <key>
             <column name="ORDER_NUMBER" />
             <column name="REVISION_NUMBER" />
       </key>
       
       <one-to-many    class="c.e.e.t.view.order.bo.nthing.AbstractPriorityNthing"/>
    </set>
   
</class>
<class    
      name="c.e.e.t.view.order.bo.foo.AbstractFoo"
      abstract="true"
      lazy="false">
         
   <composite-id
               name="fooPriority"
               class="c.e.e.t.view.order.bo.foo.Food">
         ....
   </composite-id>
   ....   
</class>

<union-subclass    
           name="c.e.e.t.view.order.bo.foo.FooA"
           table="FOO_A"
           extends="c.e.e.t.view.order.bo.foo.AbstractFoo"
           lazy="false">
      
         ....
</union-subclass>

<union-subclass    
            name="c.e.e.t.view.order.bo.foo.FooB"
            table="FOO_B"
            extends="c.e.e.tview.order.bo.foo.AbstractFoo"
            lazy="false">
      
         ....   
</union-subclass>

<union-subclass    
             name="c.e.e.t.view.order.bo.foo.FooC"
             table="FOO_C"
             extends="c.e.e.t.view.order.bo.foo.AbstractFoo"
             lazy="false">
      
      ....
</union-subclass>
</hibernate-mapping>



This is working fine unless I try to change the fooType. Let's say the Set contains FooCs. If I change the type to 'NONE' and clear the Set, the entries in FOO_C are deleted, and everything is great. However, if I change the type to FooB, clear the Set and populate it with FooB instances, when I execute merge() I get an exception that the Set contained the wrong type objects ('Object with id: null was not of the specified subclass: c.e.e.t.view.order.bo.foo.FooB (class of the given object did not match class of persistent copy)'). I want the entries in FOO_C to be deleted (as in the first case), and the new FooB instances to be persisted into FOO_B.

Is this possible? If so, what do I have to do? I've tried to clear the Set of the FooC instances and update the Set, but then I get 'instance has been deleted' on the merge.

Thanks,
Dave


I hope that this is readable. I couldn't figure out how to get it formatted properly. (Figured it out ;-} )


Last edited by dderry on Thu Jan 11, 2007 5:15 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Abstract class derivatives - solution found
PostPosted: Thu Jan 11, 2007 5:01 pm 
Newbie

Joined: Wed Jan 10, 2007 3:07 pm
Posts: 8
I hope that the lack of a response to this doesn't mean that no one has a clue how to handle this. I've found a way to make it work, but would really prefer something a bit more elegant.

What I have done is to cache the contents of the new Foo Set, and the fooType. Set the fooType to 'NONE' and clear the set. session.merge(), Then set fooType to the new value, and addAll() from the cached Set to the Foo Set. session.merge(order); tx.commit() is then happy.

Code:
            if (fooTypeChanged)
            {
                Set newFoos = new HashSet();
                String newFooType = order.getFooType();
                newFoos.addAll(order.getFooThings());
                order.getFooThings().clear();
                order.setFooType(FooType.TYPE_NONE);
                order = (Order) session.merge(order);
                session.flush();
                for (AbstractFoo foo : (Set<AbstractFoo>)newFoos)
                {
                    session.evict(foo);
                }
                order.setFooType(newFooType);
                order.getFooThings().addAll(newFoos);
            }
            order = (Order) session.merge(order);



If anyone has a cleaner solution, I *sure* would like to hear it.

Dave


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 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.