-->
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.  [ 5 posts ] 
Author Message
 Post subject: Problem loading a persistent object-tree using interfaces.
PostPosted: Fri Aug 12, 2005 6:48 am 
Beginner
Beginner

Joined: Wed Jan 19, 2005 6:07 am
Posts: 20
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:3

Mapping documents:

Code:
    <class name="no.song.b2b.dao.OrderDataDao" table="ordre">
        <id name="ordreNummer" column="ordre_data_id" unsaved-value="-1">
            <generator class="increment"/>
        </id>
        <discriminator column="data_type" type="string"/>
        <property name="orderData" column="ordre_data" type="text"/>
        <subclass name="no.song.b2b.domain.OrderDataImpl" discriminator-value="generic"/>
        <subclass name="no.song.b2b.clients.jara.JaraOrderDataImpl" discriminator-value="jara"/>
    </class>

    <class name="no.song.b2b.dao.OrderProcessDao" table="ordre_prosess">
        <id name="processId" column="prosess_id" unsaved-value="-1">
            <generator class="increment"/>
        </id>
        <discriminator column="prosess_type" type="string"/>
        <many-to-one name="orderData"
            class="no.song.b2b.dao.OrderDataDao"
            cascade="all"
            column="ordre_data"
            unique="true" />
        <subclass name="no.song.b2b.dao.JaraOrderProcessDao">
            <join table="ordre_prosess_jara">
                <key column="prosess_id"/>
            </join>
            <subclass name="no.song.b2b.clients.jara.JaraOrderProcessImpl" discriminator-value="Jara_1">
                <set name="transactions" lazy="true" inverse="true" cascade="all">
                    <key column="prosess_id"/>
                    <one-to-many class="no.song.b2b.dao.JaraTransactionDAO" />
                </set>
            </subclass>

        </subclass>

    </class>

    <class name="no.song.b2b.dao.JaraTransactionDAO" table="jara_transaksjoner">
        <id name="transactionId" column="transaksjon_id" unsaved-value="-1">
            <generator class="increment"/>
        </id>
        <discriminator column="transaksjons_type" type="string"/>
        <many-to-one name="orderProcess" cascade="all" column="prosess_id" class="no.song.b2b.dao.JaraOrderProcessDao">

        </many-to-one>
        <property name="conversationId" column="samtale_id"/>
        <property name="stateMessage" column="status_melding"/>
        <property name="state" column="status_kode"/>
        <property name="executionOrder" column="exec_order"/>

        <subclass name="no.song.b2b.clients.jara.transactions.GetCustomerByNumber" discriminator-value="customerByNumber"/>
        <subclass name="no.song.b2b.clients.jara.transactions.GetCustomerBySearch" discriminator-value="customerBySearch"/>
        <subclass name="no.song.b2b.clients.jara.transactions.GetAddressBySearch" discriminator-value="addressBySearch"/>
    </class>



The generated SQL (show_sql=true):
select orderproce0_.prosess_id as prosess1_0_, orderproce0_.ordre_data as ordre3_1_0_, orderproce0_.prosess_type as prosess2_0_ from ordre_prosess orderproce0_ left outer join ordre_prosess_jara orderproce0_1_ on orderproce0_.prosess_id=orderproce0_1_.prosess_id where orderproce0_.prosess_id=?


stack-trace :

Quote:
org.springframework.orm.hibernate3.HibernateSystemException: Exception occurred inside setter of no.song.b2b.clients.OrderProcessImpl.orderData; nested exception is org.hibernate.PropertyAccessException: Exception occurred inside setter of no.song.b2b.clients.OrderProcessImpl.orderData
org.hibernate.PropertyAccessException: Exception occurred inside setter of no.song.b2b.clients.OrderProcessImpl.orderData
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:51)
at org.hibernate.tuple.AbstractTuplizer.setPropertyValues(AbstractTuplizer.java:207)
at org.hibernate.tuple.PojoTuplizer.setPropertyValues(PojoTuplizer.java:176)
at org.hibernate.persister.entity.BasicEntityPersister.setPropertyValues(BasicEntityPersister.java:2919)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:113)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:530)
at org.hibernate.loader.Loader.doQuery(Loader.java:436)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1345)
at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:116)
at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:101)
at org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java:2471)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:351)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:332)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:113)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:167)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:79)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:621)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:614)
at org.springframework.orm.hibernate3.HibernateTemplate$1.doInHibernate(HibernateTemplate.java:389)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:312)
at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:383)
at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:378)
at no.song.b2b.dao.B2bDao.findByPrimaryKey(B2bDao.java:24)
at test.testComponent.testAll(testComponent.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:78)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:40)
... 47 more
Caused by: java.lang.ClassCastException
at no.song.b2b.clients.OrderProcessImpl.setOrderData(OrderProcessImpl.java:40)
... 52 more


Failing set-method: (the property is an OrderDataImpl, a class implementing the interface OrderDataDao)
Code:
   public void setOrderData(OrderDataDao orderData) {
        log.debug("Setting DAO-orderData "+orderData.getClass().getName());
        this.orderData = (OrderDataImpl) orderData;
    }


log from the code :
Quote:
Setting DAO-orderData org.hibernate.proxy.HibernateProxy$$EnhancerByCGLIB$$dcfea0df



Obviously the problem is that Hibernate tries to set the property using a proxy, instead of instaciating the correct subclass (which in this particulare case is no.song.b2b.clients.jara.JaraOrderDataImpl)

The mapping works fine when I save my objects, but not when I load it back.

For the test I create one OrderProcess and one OrderData, assoicate them, and save it, and immideately try to load it back using the newly generated key :
Code:
               OrderProcessDao dproc = new JaraOrderProcessImpl();
        OrderDataDao ddata = new JaraOrderDataImpl();
        ddata.setOrderData("test3");
        dproc.setOrderData(ddata);
        dao.saveOrUpdate(dproc);
        log.debug("----------");
        dao.findByPrimaryKey(OrderProcessDao.class,new Integer(dproc.getProcessId()));
        log.debug("----------");



When checking the database (MySQL), the data looks fine..

How should the mepping look like to make it work both for saving and loading ?


Top
 Profile  
 
 Post subject: Oops!
PostPosted: Fri Aug 12, 2005 2:07 pm 
Expert
Expert

Joined: Fri Jul 22, 2005 2:42 pm
Posts: 670
Location: Seattle, WA
Well, it has nothing to do with Hibernate mapping :(
Hibernate does everything correctly, and your mapping is fine the problem is JVM. In particular java.lang.reflect.Method

In the BasicPropertyAccessor Hibernate does:
method.invoke( target, new Object[] { value } );

where method is proper setter, and value is the proper implementation of the interface, but invoke throws IllegalArgumentException by unknown to me reasons.

The bottom line: it looks like there is a big problem with interfaces!

_________________
--------------
Konstantin

SourceLabs - dependable OpenSource systems


Top
 Profile  
 
 Post subject: my bad!!
PostPosted: Fri Aug 12, 2005 2:21 pm 
Expert
Expert

Joined: Fri Jul 22, 2005 2:42 pm
Posts: 670
Location: Seattle, WA
JVM is not guilty!

I did not declare that object implements my interface! Stupid me!

Hibernate and JVM works fine and set implementation to the method that requires interface ( at least current 3.1cvs)

_________________
--------------
Konstantin

SourceLabs - dependable OpenSource systems


Top
 Profile  
 
 Post subject: Sort of solution...
PostPosted: Sun Aug 14, 2005 5:24 pm 
Beginner
Beginner

Joined: Wed Jan 19, 2005 6:07 am
Posts: 20
Or maybe a workaround....

One way that makes it work directly, is to make the association not lazy by explicit telling it that it is not.

I did this in all three levels of OrderDataDao like this :
Code:
    <class name="no.song.b2b.dao.OrderDataDao" table="ordre" lazy="false" >
        <id name="ordreNummer" column="ordre_data_id" unsaved-value="-1">
            <generator class="increment"/>
        </id>
        <discriminator column="data_type" type="string"/>
        <property name="orderData" column="ordre_data" type="text"/>
        <subclass name="no.song.b2b.domain.OrderDataImpl" discriminator-value="generic" lazy="false"/>
        <subclass name="no.song.b2b.clients.jara.JaraOrderDataImpl" discriminator-value="jara" lazy="false" />
    </class>


This made Hibernate load the data-class togehter with the process-class, and the data-object could be casted to an implementing class in the set-method.

I could perhaps specified lazy=false just on the top-level, but I haven't had the time to try it out yet.


Top
 Profile  
 
 Post subject: This must be the solution because...
PostPosted: Tue Aug 16, 2005 3:01 am 
Beginner
Beginner

Joined: Wed Jan 19, 2005 6:07 am
Posts: 20
Since I need to cast the incoming parameter for the association to the top-level-abstract class of the tree, it is impossible to make use of lazy.. I need an instanciated object which implements the interface declared in the setters signature.

This is not really an limitation in Hibernate, but in the nature of Java and the usage of interfaces.


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