-->
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.  [ 6 posts ] 
Author Message
 Post subject: One to many mapping with the same class at both ends
PostPosted: Wed Dec 20, 2006 11:50 am 
Beginner
Beginner

Joined: Wed Dec 20, 2006 11:21 am
Posts: 20
Hello,

I'd like to know if it is at all possible to do a collection mapping of a class to the same class.

Eg, I have a class named Category, and this class contains a list of other categories (which are in fact subcategories).

Would Hibernate manage some how to achieve such a mapping? If not, why? Is it conceptually stupid? Should I just subclass Category by another class (Subcategory), but that would mean two SQL tables.

I have read the documentation and spent quite some time googling, but I did not find anything, so I 'll be happy to take any link or help (I am new to Hibernate).

Jean-Noël


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 20, 2006 6:04 pm 
Expert
Expert

Joined: Tue Dec 28, 2004 7:02 am
Posts: 573
Location: Toulouse, France
Absolutely no problem. This case is even a part of the CaveatEmptor. See the "book forum" to see subject about it.

Guess what, in CaveatEmptor, there's a class called Category that is self-referencing :-). The only difference with what you want to do is that Category only has a many-to-one reference to its parent. But your mapping still will be ok if considering a list of children from Category.

To see if a problem is manageable with Hibernate, just verify that it's storable in a db. If yes, you're done :). In your case, it's just a column in the Category table which references its parent.

HTH.

_________________
Baptiste
PS : please don't forget to give credits below if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 20, 2007 11:20 am 
Beginner
Beginner

Joined: Wed Dec 20, 2006 11:21 am
Posts: 20
Good to know that it can be done. However, I cannot manage to accomplish it. Here is my mapping:

<hibernate-mapping>
<class name="com.example.client.Category" table="ShopCategories">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="name" />

<set access="field" name="subcategories_list">
<key column="parent_category_id" />
<one-to-many class="com.example.client.Category"/>
</set>

<!-- The non-inverse side of the one-to-many/many-to-one association -->
<many-to-one name="parent_category"
class="com.example.client.ShopCategory"
access="field"
foreign-key="FK_CATEGORY_PARENT_ID">
<column name="parent_category_id"
not-null="false"/>
</many-to-one>

</class>
</hibernate-mapping>

I had a look at the CaveatEmptor example you mentionned, they are doing things a little bit differently there since they use a bag... like this:

<!-- The inverse side of the one-to-many/many-to-one association, we
use a bag mapping, iteration order of this collection is by
category name. -->

<bag name="childCategories"
cascade="save-update, merge"
inverse="true"
order-by="CATEGORY_NAME asc">
<key column="PARENT_CATEGORY_ID"/>
<one-to-many class="Category"/>
</bag>

Can anyone tell me what's wrong with my mapping?

Jean-Noël

EDIT: I forgot to ask that with this mapping, at run time I get the exception and following stack trace:

ERROR http-8080-Processor25 org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/Shop] - Exception while dispatching incoming RPC call
java.lang.ClassCastException: java.util.ArrayList
at org.hibernate.type.SetType.wrap(SetType.java:39)
at org.hibernate.event.def.WrapVisitor.processArrayOrNewCollection(WrapVisitor.java:84)
at org.hibernate.event.def.WrapVisitor.processCollection(WrapVisitor.java:51)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor.java:98)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at org.hibernate.event.def.AbstractSaveEventListener.visitCollectionsBeforeSave(AbstractSaveEventListener.java:333)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:250)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:167)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:101)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:530)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:518)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:514)
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:585)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
at $Proxy0.save(Unknown Source)
at com.example.server.ShopServicesImplementation.test(ShopServicesImplementation.java:80)
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:585)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:281)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:167)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 20, 2007 12:34 pm 
Beginner
Beginner

Joined: Wed Dec 20, 2006 11:21 am
Posts: 20
I got it working. Turned out I was using a List on the Java side, when I used a Set in the mapping.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 20, 2007 12:38 pm 
Expert
Expert

Joined: Tue Dec 28, 2004 7:02 am
Posts: 573
Location: Toulouse, France
That's a good thing you added the exception. Could you provide your beans? I guess you specified a set mapping and are actually using a List or even an ArrayList in the code => ClassCastException...

_________________
Baptiste
PS : please don't forget to give credits below if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 20, 2007 12:50 pm 
Beginner
Beginner

Joined: Wed Dec 20, 2006 11:21 am
Posts: 20
Yes, as I posted just before you posted (you probably did not read that), I solved the problem, and it was due to me using a List on the Java side.


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