-->
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.  [ 14 posts ] 
Author Message
 Post subject: Loading wrong Class-Instance
PostPosted: Fri Sep 30, 2005 10:10 am 
Beginner
Beginner

Joined: Tue Mar 15, 2005 5:04 am
Posts: 26
Hi,

I have some Problems with Hibernate and instancing the right Objects.

I have one Class named Account. This is abstract. Two additional Classes
inherite from Account and are named DAccount and KAccount.
The have discriminatiors in the Database.

In the Class Partner I have a Set of Account:

<set name="accounts">
<key column="partner_id"/>
<one-to-many class="de.datentraum.allrounder.BaseClasses.Account"/>
</set>

When I load a Partner, hibernate instanciates the right Objects. DAccount or KAccount. Never Account.

Now I have next Class named Process, related to one Account. Either DAccount or KAccount.
Mapped like this.

<many-to-one name="account" column="account_id"/>


(I had set the class-attribute to class="Account" before, but it had the same Problem)

When I load the Processes with Hibernate it loads the account related to aswell. But it does not instanciate DAccount but some Account class enhanced by CGlib.

How can I traet hibernate to load the correct Class. I need some Methods that are placed in DAccount if the Account is stored as DAccount in the Database.

Would be very happy if someone could help me.
Thx,
Alexander
Hibernate version: 3.0


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 30, 2005 11:31 am 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
Take a look at using a proxy interface as explained here: http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#inheritance-tableperclass.

_________________
nathan


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 30, 2005 11:52 am 
Beginner
Beginner

Joined: Tue Mar 15, 2005 5:04 am
Posts: 26
Hi,
thanks for your Reply

Code:
<hibernate-mapping>
   <class name="de.datentraum.allrounder.BaseClasses.Account" table="accounts" abstract="true">
      <id name="id" type="int" column="account_id" unsaved-value="0">
         <generator class="sequence">
            <param name="sequence">uid_account</param>
         </generator>
      </id>
      <discriminator column="disc"/>
      <property name="accountnumber" type="int"/>
      <property name="con" column="condition" type="int"/>
      <many-to-one name="partner" column="partner_id" class="de.datentraum.allrounder.BaseClasses.Partner" />
      <many-to-one name="tax" column="tax" class="de.datentraum.allrounder.BaseClasses.Tax" />
      <set name="articleRelations">
         <key column="account_id"/>
         <one-to-many class="de.datentraum.allrounder.BaseClasses.ArticleRelation"/>
      </set>
      <set name="processes">
            <key column="account_id"/>
            <one-to-many class="de.datentraum.allrounder.Processes.Process"/>
      </set>
      <subclass name="de.datentraum.allrounder.BaseClasses.DAccount" discriminator-value="D">
      </subclass>
      <subclass name="de.datentraum.allrounder.BaseClasses.KAccount" discriminator-value="K">
      </subclass>
   </class>
</hibernate-mapping>


I Did map the Classes that way. And hibernate loads the correct classes when I have the Acounts in a Set. <one-to-many>
But it does not work in the Process-class being mapped like this:

Code:
<hibernate-mapping>
   <class name="de.datentraum.allrounder.Processes.Process" table="process" >
      <id name="id" type="int" column="process_id" unsaved-value="0">
         <generator class="sequence">
            <param name="sequence">uid_process</param>
         </generator>
      </id>
      <discriminator column="disc"/>
      <many-to-one name="account" column="account_id"/>
      <set name="documents">
            <key column="process_id"/>
            <one-to-many class="de.datentraum.allrounder.Processes.Document"/>
      </set>
      <subclass name="de.datentraum.allrounder.Processes.DProcess" discriminator-value="DPRO">
      </subclass>
      <subclass name="de.datentraum.allrounder.Processes.KProcess" discriminator-value="KPRO">
      </subclass>
      
   </class>
</hibernate-mapping>


In this case, account will be from a newly enhanced class by CGlib.
But it should be from the Class DAccount or KAccount.

Any further Ideas?

Thx,
Alexander


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 30, 2005 12:03 pm 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
Oops. The link didn't paste right. Here's the link: http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#performance-fetching-proxies.

I checked it this time :)

_________________
nathan


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 02, 2005 9:21 am 
Beginner
Beginner

Joined: Tue Mar 15, 2005 5:04 am
Posts: 26
Hmm, this is hard.
Why doesn't Hibernate simply initiate the subclass but creates an enhanced one, when it can work with it without any problems in Sets?
Don't get that.

Do I really have to create Interfaces for each subclass I have, or did I get something wrong? I simply whant a many-to-one relation where Hibernate notices by a discriminator that it has to load a subclass.

Is there no other way?

Thx,
Alexander


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 03, 2005 9:56 am 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
I don't think so, not if you want lazy-loading (proxies). If you set lazy="false", I believe everything will work correctly, without having to create interfaces.

What I think would be cool is if hbm2java could create the interfaces for us. I think it's already in the Tools JIRA, but not likely to be implemented soon.

_________________
nathan


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 05, 2005 11:04 am 
Beginner
Beginner

Joined: Tue Mar 15, 2005 5:04 am
Posts: 26
Ok, thank you very much.

But I still have a Problem. Now its with the Interfaces.

I made up all instances for the Classes Account, DAccount and KAccount and
wrote them into the Mappingfile as being the proxy.

When I am loading no a Process, which has a Account in it, I recieve this error I allready had.
Quote:
org.hibernate.PropertyAccessException: exception setting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) setter of de.datentraum.allrounder.Processes.DProcess.setAccount


This is the Source:

Code:

   /* (non-Javadoc)
    * @see de.datentraum.allrounder.Processes.Process#setAccount(de.datentraum.allrounder.BaseClasses.Account)
    */
   public void setAccount(Account acc) {
      if (acc != null){
         if(!(acc.getType()==Account.D)){
            //ApplicationConf.getCurrentMessanger().failureMessage("Falsches Konto: "+acc.toString());
         }else{
            this.account = (Account) acc;
            //((DAccountInt)acc).test();
         }
      }
   }



Any Idea??

thx,
Alexander


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 05, 2005 12:40 pm 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
Follow the suggestion from the exception (set hibernate.cglib.use_reflection_optimizer=false for more info) to see if it gives you a better indication of the problem.

_________________
nathan


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 05, 2005 1:43 pm 
Beginner
Beginner

Joined: Tue Mar 15, 2005 5:04 am
Posts: 26
Hi,

I allready Did. the flag is set to false, but it does not give any further hints :-(


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 05, 2005 2:27 pm 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
I've only played around with the proxy interfaces, but I remember having troubles figuring out if I should reference the Impl or the Interface from other mapping files (the docs were hard to understand in this area). Seems like I might have had to reference the interface instead of the impl. Have you tried that?

Also, in general, it's hard for others to help out/give suggestions if you don't post full stack traces, etc.

_________________
nathan


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 6:08 am 
Beginner
Beginner

Joined: Tue Mar 15, 2005 5:04 am
Posts: 26
Hi,
I think they have to be in the MappinDoc for the class being interfaced.
I think if I put it to the reference, i wouldn't be able to use Polymorphism, would I?

I would love to give you more stacktrace than I allready did, but

Quote:
org.hibernate.PropertyAccessException: exception setting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) setter of de.datentraum.allrounder.Processes.DProcess.setAccount



is the only line I get. Even though I set hibernate.cglib.use_reflection_optimizer to false

I am totally stuck :-(


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 6:28 am 
Beginner
Beginner

Joined: Tue Mar 15, 2005 5:04 am
Posts: 26
Ok, forgot that i can call the printStackTrace Method.
Here ist the full Stack.

Quote:
org.hibernate.PropertyAccessException: exception setting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) setter of de.datentraum.allrounder.Processes.DProcess.setAccount
at org.hibernate.tuple.PojoEntityTuplizer.setPropertyValuesWithOptimizer(PojoEntityTuplizer.java:215)
at org.hibernate.tuple.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:185)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3206)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:126)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:223)
at org.hibernate.loader.Loader.doList(Loader.java:2147)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2026)
at org.hibernate.loader.Loader.list(Loader.java:2021)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1452)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:298)
at de.datentraum.allrounder.GUI.FrmProcessOverview.loadProcesses(FrmProcessOverview.java:68)
at de.datentraum.allrounder.GUI.FrmProcessOverview.show(FrmProcessOverview.java:55)
at de.datentraum.allrounder.GUI.FrmMain$1.mouseDoubleClick(FrmMain.java:82)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:141)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:843)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3080)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2713)
at de.datentraum.allrounder.GUI.FrmMain.execute(FrmMain.java:109)
at de.datentraum.allrounder.Main.AllRounder.main(AllRounder.java:31)
Caused by: net.sf.cglib.beans.BulkBeanException
at de.datentraum.allrounder.Processes.DProcess$$BulkBeanByCGLIB$$5c25250b.setPropertyValues(<generated>)
at org.hibernate.tuple.PojoEntityTuplizer.setPropertyValuesWithOptimizer(PojoEntityTuplizer.java:212)
... 22 more
Caused by: java.lang.ClassCastException
... 24 more


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 10:49 am 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
theaim wrote:
Hi,
I think they have to be in the MappinDoc for the class being interfaced.
I think if I put it to the reference, i wouldn't be able to use Polymorphism, would I?


Not sure I understand what you mean when you say you wouldn't be able to use polymorphism. Your DAccount and KAccount interfaces should extend your Account interface (same hierarchy as your pojos), and then when you access you Account from your Process, Hibernate will be able to load either your DAccount or KAccount correctly (the Account interface returned will really be either a DAccount interface or KAccount interface).

Again, this is going mostly from memory, from when I was trying it out a while back. I may be wrong.

_________________
nathan


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 11:12 am 
Beginner
Beginner

Joined: Tue Mar 15, 2005 5:04 am
Posts: 26
Hi,
What I simply ment was, that if you put Proxy="" in
the many-to-one relation, you would bind either DAccount or KAccount to that interface you put as proxy.
But as I looked in the Docs i saw, that proxy isnt an many-to-one attribute.

I am currently working fine with lazy=true. But would like to implement the Proxies for the future.

Do you have any Idea to the stack?

Thanks for your patience with me ;-)

regards,
Alexander


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