-->
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.  [ 12 posts ] 
Author Message
 Post subject: map a class that is only a container for another class
PostPosted: Wed Nov 19, 2008 3:38 pm 
Newbie

Joined: Tue Sep 23, 2008 4:44 pm
Posts: 15
I have three classes A, B, C as shown below.


Code:
class A {
  B b;  // an instance of B
   // some other attributes
}

class B {
  C[] c;  // an array of C instances
  // has NO other attributes
}


class C {
   // has some attributes
}



I have mapped A and C using hibernate to tables T_A and T_C.

My question is, what mapping should I use for class B? Since its only a container for instances of C in an array and does not have any other attributes, it cannot have its own table. Yet hibernate has to know that it needs to create instance of B, and add instances of "C" to it.

Appreciate any responses.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2008 3:53 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
You should map B as a "component" class of A. Example from the docs:
Code:
<class name="eg.Person" table="person">
    <id name="Key" column="pid" type="string">
        <generator class="uuid"/>
    </id>
    <property name="birthday" type="date"/>
    <component name="Name" class="eg.Name"> <!-- class attribute optional -->
        <property name="initial"/>
        <property name="first"/>
        <property name="last"/>
    </component>
</class>


Person has a table but Name doesn't. The fields in Name are populated by entries from the person table.

Similarly, the fields of B could be populated by whatever database linkage there is between A and C.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2008 5:23 pm 
Newbie

Joined: Tue Sep 23, 2008 4:44 pm
Posts: 15
Thanks. I looked at "component" tag, but it doesn't support <one-to-many> mapping from B to C:
Code:
<class name="A">
  <component name="b">
        <one-to-many class="C"/> <!-- This isn't supported by component tag -->
   </component>
</class>


Are there any workarounds, should "arrays" be used instead?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2008 1:53 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
You need to use the array/list/set tag like you would for any other one-to-may:
Code:
   <component name="b">
      <array name="c">
         <key column="a_id"/>
         <index column="ordering"/>
         <one-to-many class="C"/>
      </array>
   </component>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2008 2:08 pm 
Newbie

Joined: Tue Sep 23, 2008 4:44 pm
Posts: 15
Two more questions. Thank you for the answers.

1)
Quote:
the fields of B could be populated by whatever database linkage there is between A and C
Code:
<key column="a_id"/>



is "a_id" in this case the foreign key in "TABLE_C" from the "TABLE_A"? Does "key column" denote a foreign key in "TABLE-A" or "TABLE-C".

2) I read relevant parts of the hibernate manual, but have some confusion about where foreign keys need to be created, and how the mapping of keys is defined.

The following mapping for the case below does not work. The problem with this seems to be that it expects a foreign key "e_id" from "TABLE_E" to be in TABLE_D. But that is reversing the parent-child relationship.

2.1) Should the mapping instead be defined as <many-to-one> in E.hbm.xml, and omit the <one-to-many> in D.hbm.xml? Then E cannot be navigated from D.

2.2) When defining <one-to-many> in D.hbm.xml, the "TABLE_E.d_id" foreign key is not "accessible", correct?

Code:
<class name="D">
   <one-to-many name="e" column="d_id" class="E" />
</class>


class D {
  E[] e;
}

create TABLE_D (d_id, d_c1, d_c2);
create TABLE_E (e_id, e_c1, d_id references TABLE_D.d_id) // i.e d_id is a FK


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2008 3:06 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Have you read the following two chapters in the Hibernate reference documentation? If not, I think you should since it explains a lot of things, with <many-to-one>, <one-to-many> and more...

http://www.hibernate.org/hib_docs/v3/re ... tions.html

http://www.hibernate.org/hib_docs/v3/re ... bidir.html


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2008 3:07 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Yes, a_id is a column in table C that refers to the primary key of A, as a foreign key. This is how you know which instances of C belong to each A.

2 - Its unclear why a foreign key to E is expected to be in D. Perhaps your mapping of the reverse relationship from E to D (not shown) is incorrect.

2.1 - If you need to navigate in both directions you can define the mapping as one-to-many in the parent AND many-to-one in the child to create a bi-directional relationship. Remember to set the inverse="true" flag on one end - probably the parent.

2.2 - Well, if you define a uni-directional relationship from D to E then run a query that returns you instances of E then you're correct, you can't access the column value even though its there in the db. But if you need D from E you wouldn't do this.

If you navigate to E from an instance of D you already know the value of the column in E - its the primary key of that instance of D.

If you have a bi-directional relationship and you run the query for E then you also know the value from the primary key of the associated D.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2008 5:28 pm 
Newbie

Joined: Tue Sep 23, 2008 4:44 pm
Posts: 15
Are the mappings below correct?

Code:
class D {
  String dId;
  E e;
  .....
}

class E {
  String eId;
  String ec1;
  .....
}

D.hbm.xml
<class name="D">
   <id name="d_id" column="d_id" />

   <many-to-one name="e"
          column="d_id"
          unique="true"
          class="E"
          cascade="all"
          not-null="false"
          update="false"
          insert="false"
          />
</class>

E.hbm.xml
<class name="D" table="TABLE_E">
   <id name="e_id" column="e_id" />
    <many-to-one name="d" column="d_id"  class="D" unique="true" not-null="false"/>
</class>


But this doesn't populate the FK E.d_id.

What I want to do is:
1) Navigate D->E
2) Use FK d_id in E to denote parent-child relationship D->, but not have to use FK of E in D. And can't use Join table such as TABLE_D_E(d_id, e_id) used in the hibernate example.
If I dont need to navigate E->D, do I still need to define a <many-to-one> mapping in E.hbm.xml?

Looks like the FK E.d_id can only be mapped from within E.hbm.xml, and not inside D.hbm.xml?

I have been referring to example 7.2.2 at "http://www.hibernate.org/hib_docs/reference/en/html/assoc-unidirectional.html".


Last edited by smpub2000 on Thu Nov 20, 2008 6:02 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2008 5:48 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
Are the mappings below correct?


No, a <one-to-many> have to go in a <set> or other collection tag. For example:

Code:
<class name="D">
  <id name="d_id" column="d_id" />
  <set name="e" inverse="true">
    <key column="d_id">
    <one-to-many class="E">
  </set>
</class>


By the way. Doesn't Hibernate complains when you have the <one-to-many> by itself. If I do like this I get the error message:
Code:
org.xml.sax.SAXParseException: The content of element type "class" must match "(meta*,subselect?,cache?,synchronize*,comment?,tuplizer*,(id|composite-id),discriminator?,natural-id?,
(version|timestamp)?,(property|many-to-one|one-to-one|component|dynamic-component|properties|any|map|set|list|bag|idbag|array|primitive-array)*,
((join*,subclass*)|joined-subclass*|union-subclass*),loader?,sql
-insert?,sql-update?,sql-delete?,filter*,resultset*,(query|sql-query)*)".


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2008 6:11 pm 
Newbie

Joined: Tue Sep 23, 2008 4:44 pm
Posts: 15
I have updated the example in my previous post to use "many-to-one", which is what is should have been, my apologies. Another way to put it is, in the example 7.2.2,
http://www.hibernate.org/hib_docs/refer ... ional.html
I want to change the schema from
Code:
create table Person ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )


to
Code:
create table Person ( personId bigint not null primary key )
create table Address ( addressId bigint not null primary key,  personId foreign key references Person.personId)


But I want to be able to navigate from Person->Address. Similarly, D->E. What needs to change in the mapping(s) and the code? And do that using a foreign key, not join tables.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2008 6:23 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
After the edit, I think nothing makes sense any more. Now you have what is essentially a <one-to-one> mapping between D and E.

What do you really want. Given a single D does it have one E or many E:s? And given a single E, does it have one D or many D:s?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2008 7:24 pm 
Newbie

Joined: Tue Sep 23, 2008 4:44 pm
Posts: 15
After the edit, D to E is a one-to-one mapping. D is the parent, and it can have 0 or 1 instances of E. So I want to know what changes in the code for D, E, and the mappings D.hbm.xml and E.hbm.xml.


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