-->
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.  [ 1 post ] 
Author Message
 Post subject: Issue:Mix table per class hierarchy with table per subclass
PostPosted: Mon Oct 04, 2010 5:54 pm 
Newbie

Joined: Mon Oct 04, 2010 5:37 pm
Posts: 1
Hi All

I have a very deep class hierarchy in my domain model and want to use discriminator tag to support inheritance.

Initially i mapped my classes using join-subclass, however the tables involved have hundreds of thousands of records and it is turning out to be a performance bottleneck. So in essence i want to flatten my table structure without touching the domain and that's why we moved on to discriminator tag.

My hibernate mappings looks like(have deleted the extra column for sake of simplicity)

Code:
<!--Hibernate mapping for Transaction-->
<hibernate-mapping>

   <class name="Transaction"
      table="transaction" abstract="true">
        ..........
       
        <discriminator column="transaction_type" type="string"/>
       .........

   </class>

</hibernate-mapping>


<!--Hibernate mapping for CashBasedTrsansaction having all the subsequent child classes-->
<hibernate-mapping>
<subclass name="CashBasedTransaction"
          extends="Transaction" discriminator-value="CASH">
     <join table="cash_based_transaction">
       <key column="id" />
     </join>
   
     <subclass discriminator-value="BILLING"
      name="BillingTransaction">
      <join table="billing_transaction">
         <key column="id" />
         <many-to-one name="invoice" column="invoice_id" cascade="all" access="field"
            lazy="false">
         </many-to-one>
      </join>
     
      <subclass name="ChildBillingTransaction"
         discriminator-value="UPT">
         <join table="billing_transaction">
            <key column="id" />
            ...............
         </join>
      </subclass>
      <subclass abstract="true"
         name="AnotherChildOfBillingTransaction"
         discriminator-value="LPT">

         <subclass
            name="SuperChildOfBillingTransaction"
            discriminator-value="OCLPT">
            <join table="billing_transaction">
               <key column="id" />
               ...........
            </join>
         </subclass>
         <subclass
            name="AnoherSuperChildOfBillingTransaction"
            discriminator-value="SLPT">
            <join table="billing_transaction">
               <key column="id" />
               ..........
            </join>
         </subclass>
      </subclass>
   </subclass>
</hibernate-mapping>

<!--Hibernate mapping for Invoice-->
<hibernate-mapping>
   
   <class name="Invoice" table="invoice">
      .......

      <bag name="billingTransactions"  access="field" cascade="all" inverse="true" table="billing_transaction">
         <key column="invoice_id" />
         <one-to-many class="BillingTransaction" />
      </bag>

      .......     

   </class>
</hibernate-mapping>



What i want to achieve
: I want to flatten out table structure after billing_transaction. In other words i want to have only three tables in the database

- transaction
- cash_based_transaction
- billing_transaction(this table should hold all the columns after flattening out all the subclasses)

P.S : Please note that i want to flatten out table structure not from the aggregate root(read transaction) but somewhere down the line in my class hierarchy, billing_transaction in this case.


Problem : Hibernate is creating a column "invoice_id" in transaction table(this is wrong) as well as in billing_transaction(this is correct). On further debugging i found some interesting results and need some feedback/advice.

- Hibernate creates a column invoice_id in billing_transaction which is what i want. The following code is responsible for it

Code:
<join table="billing_transaction">
         <key column="id" />
         <many-to-one name="invoice" column="invoice_id" cascade="all" access="field"
            lazy="false" index="billing_transaction_n1">
         </many-to-one>
      </join>


- Hibernate also creates invoice_id in Transaction which is not what i want. The following code is responsible for it...

Code:
<bag name="billingTransactions"  access="field" cascade="all" inverse="true" table="billing_transaction">
         <key column="invoice_id" />
         <one-to-many class="BillingTransaction" />
      </bag>


Now this is frustrating. Even though i have mentioned the table name and have set inverse="true" yet hibernate goes ahead and create a column invoice_id in transaction table. I was expecting that since i am giving it the table name hibernate should take that name and check if billing_transaction has invoice_id or not... Instead hibernate is doing exactly opposite. It is completely ignoring the table name that i have provided and reaching out to the most super class i.e. Transaction. There it creates invoice_id column when it finds out that no such column exists. As a result i have two invoice_id column sitting in my tables. One in billing_transaction where i want it to be and another in transaction table where i don't want it to be.



I have found out the code which is causing it. In org.hibernate.mapping.Subclass table is identified using the below given code

Code:
public Property getIdentifierProperty() {
      return getSuperclass().getIdentifierProperty();
   }


In other words hibernate is assuming that whenever someone is using subclass all the columns should be create in the top root of the class hierarchy irrespective of what table name has been provided. Can someone please explain the reasoning behind it and if there is way to bypass this code and somehow avoid invoice_id getting created in transaction table???


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

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.