-->
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.  [ 3 posts ] 
Author Message
 Post subject: table-per-subclass, discriminator using formula
PostPosted: Wed Sep 16, 2009 3:09 pm 
Newbie

Joined: Wed May 07, 2008 8:00 pm
Posts: 3
I'm attempting a table-per-subclass mapping using a discriminator that is from a formula

Basically if the group type of the carrier is 1, then I need to get the product codes from 'CFG_PRODUCT_CODE', if the carrier group type is 0, then I want to get the product codes from CFG_RELOAD_PROD_CODE. I also plan on using this on inserts as well.

I get a stack trace when I run with this mapping. Debugging in the hibernate code it looks like it is looking for a discriminator value for the ProductCode class. It is abstract, so I wouldn't expect it needing a discriminator.

I'm dealing with a legacy DB and so I can't modify the table structures.

Any help is appreciated.
Jason
Hibernate 3.2 with oracle.


Code:

<class name="com.vincent.ProductCode" abstract="true" >
        <composite-id>
            <key-many-to-one name="carrier"/>
            <key-many-to-one name="platform"/>
            <key-many-to-one name="exspplat"/>
            <key-property name="code"/>
        </composite-id>

        <discriminator formula="select a.sp_group_type from VINCENT.tbl_carrier a where CARRIER_ID = a.CARRIER_ID" type="integer"/>
        <subclass name="com.vincent.PrepaidProductCode" discriminator-value="1">
            <join schema="VINCENT" table="CFG_PRODUCT_CODE">
                <key>
                    <column name="CARRIER_ID"/>
                    <column name="PLAT_ID"/>
                    <column name="EXSPPLAT_ID"/>
                    <column name="PRODUCT_CODE"/>
                </key>
                <property name="denomination" column="DENOMINATION"/>
            </join>
        </subclass>
        <subclass name="com.vincent.BillpayProductCode" discriminator-value="0">
            <join schema="VINCENT" table="CFG_RELOAD_PROD_CODE">
                <key>
                    <column name="CARRIER_ID"/>
                    <column name="PLAT_ID"/>
                    <column name="EXSPPLAT_ID"/>
                    <column name="PRODUCT_CODE"/>
                </key>
            </join>
        </subclass>
    </class>




Code:
org.hibernate.MappingException: Could not format discriminator value to SQL string
   at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:307)
   at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:55)
   at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:226)
   at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1300)
   at com.vincent.HibernateConnectionPool.init(HibernateConnectionPool.java:101)
   at com.vincent.HibernateConnectionPool.getCurrentSession(HibernateConnectionPool.java:119)
   at com.vincent.gwtapps.server.ProductCodeServicesImpl.getProductCodes(ProductCodeServicesImpl.java:25)
   at com.vincent.gwtapps.server.ProductCodeServicesTestCase.testGetProductCodes(ProductCodeServicesTestCase.java:20)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at junit.framework.TestCase.runTest(TestCase.java:168)
   at junit.framework.TestCase.runBare(TestCase.java:134)
   at junit.framework.TestResult$1.protect(TestResult.java:110)
   at junit.framework.TestResult.runProtected(TestResult.java:128)
   at junit.framework.TestResult.run(TestResult.java:113)
   at junit.framework.TestCase.run(TestCase.java:124)
   at junit.textui.TestRunner.doRun(TestRunner.java:116)
   at com.intellij.rt.execution.junit.IdeaTestRunner.doRun(IdeaTestRunner.java:94)
   at junit.textui.TestRunner.doRun(TestRunner.java:109)
   at com.intellij.rt.execution.junit.IdeaTestRunner.startRunnerWithArgs(IdeaTestRunner.java:22)
   at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:118)
   at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
Caused by: java.lang.NumberFormatException: For input string: "com.vincent.ProductCode"
   at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
   at java.lang.Integer.parseInt(Integer.java:447)
   at java.lang.Integer.<init>(Integer.java:620)
   at org.hibernate.type.IntegerType.stringToObject(IntegerType.java:55)
   at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:300)
   ... 23 more


Top
 Profile  
 
 Post subject: Re: table-per-subclass, discriminator using formula
PostPosted: Thu Sep 17, 2009 12:24 pm 
Newbie

Joined: Wed May 07, 2008 8:00 pm
Posts: 3
The stack trace was caused by Hibernate using it's default behavior and was converting the classname into a discriminator value since one wasn't specified.

I was able to find a suitable mapping to load the single super-class from 2 tables.

BUT, with this new mapping, when creating new objects, the logic for figuring out which subclass should be instantiated is now moved into my domain layer logic. Good enough for my needs, but not ideal.

Code:
    <class name="com.vincent.ProductCode" abstract="true">
        <composite-id>
            <key-many-to-one name="serviceProvider" column="CARRIER_ID"/>
            <key-many-to-one name="platform" column="PLAT_ID"/>
            <key-many-to-one name="exspplat" column="EXSPPLAT_ID"/>
            <key-property name="code" column="PRODUCT_CODE"/>
        </composite-id>
        <union-subclass name="com.vincent.PrepaidProductCode" batch-size="10"
                        schema="VINCENT"
                        table="CFG_PRODUCT_CODE">
            <property name="denomination" column="DENOMINATION"/>
        </union-subclass>
        <union-subclass name="com.vincent.BillpayProductCode" batch-size="10"
                        schema="VINCENT" table="CFG_RELOAD_PROD_CODE">
        </union-subclass>
    </class>


Thanks all,
Jason


Top
 Profile  
 
 Post subject: Re: table-per-subclass, discriminator using formula
PostPosted: Thu Dec 30, 2010 7:18 pm 
Newbie

Joined: Thu Dec 30, 2010 6:58 pm
Posts: 5
It was brought up a bunch of times in 2004, was supposed to be resolved in 3.X (see viewtopic.php?f=1&t=930140), but as of last year still wasn't (see viewtopic.php?f=1&t=978934).

By default, Hibernate is still trying to convert the classname into a discriminator value if one wasn't specified for the superclass.

You don't have to do what you did - just put a dummy discriminator-value attribute into the superclass. If you have a formula-based discriminator, it is very easy to ensure that this value will never be returned.

But really, I don't understand why this should be necessary. If superclass was NOT abstract, would you be able to give it a real discriminator-value and instantiate it? I haven't tried and don't think it's documented. Neither is the possibility of using int type discriminator (as opposed to integer) - but I tried and it works just fine.

When superclass has attribute abtract="true", though, Hibernate should be smart enough NOT to attempt to bind it to a discriminator-value... Can't it just provide a dummy one by default?


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