-->
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.  [ 15 posts ] 
Author Message
 Post subject: Collection Mapping & Subclasses
PostPosted: Wed May 04, 2005 10:03 pm 
Newbie

Joined: Wed May 04, 2005 9:06 pm
Posts: 1
Is it possible to map a collection of polymorphic objects when the foreign key exists only on the superclass (table-per-subclass)? I attempted to implement such a mapping earlier today, but found that things weren't as easy as I had envisioned when I started.

I guess my real question is, "Must the column specified in <key/> reside in the table defined by the subclass?" If this is indeed the case, is this intentional or a bug and are there any workarounds?

I am using Hibernate 3.0.2 with PostgreSQL 7.4.7.

Issue/Error:

The error returned when I attempt to call Person.getProductDownloads() is ERROR: column productdow0_.person does not exist.

Generated SQL:

When Hibernate generates the SQL for the collection, it uses the table alias for the collection table (e.g. product_downloads) instead of the joined downloads table. [em]The statement below references my particular setup that contains schemas/catalogs in PostgreSQL.[/em]

Code:
select productdow0_.person as person__, productdow0_.download as download__, productdow0_.download as id0_, productdow0_1_.person as person3_0_, productdow0_.release as release4_0_ from products.downloads productdow0_ inner join public.downloads productdow0_1_ on productdow0_.download=productdow0_1_.id where productdow0_.person=?


POJOs:

Code:
public abstract class Download {
  ...
  private Integer id;
  private Person person;
  ...
}

public class ProductDownload extends Download {
  ...
  private Release release;
  ...
}

public class ... extends Download {
  ...
}


Mappings:

Code:
<hibernate-mapping>
  <class name="Download" table="downloads" schema="public">
    <id name="id">
      <generator class="sequence">
        <param name="sequence">downloads_id_seq</param>
      </generator>
    </id>
    ...
    <many-to-one name="person" class="Person" />
    ...
    <joined-subclass name="ProductDownload" table="product_downloads" schema="products">
      <key column="download" />
      ...
      <many-to-one name="release" class="Release" />
      ...
    </joined-subclass>
    <joined-subclass name="..." table="..." schema="...">
      <key column="download" />
      ...
    </joined-subclass>
  </class>
</hibernate-mapping>

<hibernate-mapping>
  <class name="Person" table="persons" schema="contacts">
    <id name="id">
      <generator class="sequence">
        <param name="sequence">persons_id_seq</param>
      </generator>
    </id>
    ...
    <property name="name" />
    <property name="email" />
    ...
    [b]<set name="productDownloads" inverse="true">
      <key column="person" />
      <one-to-many class="ProductDownload"  />
    </set>[/b]
  </class>
</hibernate-mapping>


Schema:

Code:
CREATE TABLE public.downloads (
  id serial NOT NULL,
  person integer NOT NULL,
  ...
  PRIMARY KEY (id),
  ...
  FOREIGN KEY (person) REFERENCES contacts.persons (id)
  ...
);

CREATE TABLE products.downloads (
  download integer NOT NULL,
  release integer NOT NULL,
  ...
  PRIMARY KEY (download),
  ...
  FOREIGN KEY (download) REFERENCES public.downloads (id),
  FOREIGN KEY (release) REFERENCES products.product_releases (id)
  ...
);



Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 19, 2005 3:35 pm 
Newbie

Joined: Fri May 06, 2005 6:04 pm
Posts: 11
Location: ES - Brazil
Hi,

did you find a answer for this?


Thanks
Pedro


Top
 Profile  
 
 Post subject: Re: Collection Mapping & Subclasses
PostPosted: Tue Jul 19, 2005 4:56 pm 
Expert
Expert

Joined: Mon Feb 14, 2005 12:32 pm
Posts: 609
Location: Atlanta, GA - USA
jsmecham wrote:

I guess my real question is, "Must the column specified in <key/> reside in the table defined by the subclass?" If this is indeed the case, is this intentional or a bug and are there any workarounds?



I think I might be missing something in your question but...

The column identified by <key/> is how the JOIN is performed on the two tables. The ID field of the <class> definition and the <key/> of the <joined-subclass>

I use this quite a lot.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 20, 2005 3:04 am 
Newbie

Joined: Thu Jan 13, 2005 6:24 pm
Posts: 12
I have ran into this problem as well. The problem is that there is no way to tell hibernate that the foreign key is in the base class. I haven't found a way to do this. Hibernate seems to ignore the inheritance relationship and blindly just always asumes that the foreign key is in the derived class' table.

I also want to know if this is considered a bug and if there is a good workaround to make collections of derived types using joined-subclass strategy.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 20, 2005 3:09 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
No it is not a bug. It is very sane.

You can, of course, map it as a collection of the supertype.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 20, 2005 3:12 am 
Newbie

Joined: Thu Jan 13, 2005 6:24 pm
Posts: 12
Your reply is very criptic. Is there no way to have a collection of derived classes if you are using the joined-subclass strategy? What is the issue that would make this not sane?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 20, 2005 3:23 am 
Newbie

Joined: Thu Jan 13, 2005 6:24 pm
Posts: 12
It seems to me hibernate has all the information it needs to pull this off. When using the joined-subclass you're going to have to join the base/derived class tables anyhow. All that needs to change is which table the WHERE get's applied (where base.fk = ? ) of (where derived.fk = ? ). Doing collections of the parent class where the derived class is what's needed is very inconvenient. You'd have to add a where class and then manually cast all the elements down to the derived class. If you're hierearchy is somwhat deep this becomes very unwieldy. I guess I'm trying to understand what the limitation of adding some parameter to the mapping that would allow better control of this would be.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 20, 2005 3:32 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Sorry, you are wrong. It is MUCH more complex. *Think* about it.

Say I am loading this by outer join. So according to your suggestion I gotta outer join to the base class table. Now I gotta somehow filter out base class instances that are not subclass instances by somehow "swapping" to an inner join into the subclass table halfway down the join tree?????

I don't get how this could possibly work. Have you actually tried to write SQL to do this??

Anyway, what you are trying to do seems utterly broken from a data modelling standpoint. My recommendation to people who want to do stuff like this is always: go buy a book and learn more about data modelling.


Last edited by gavin on Wed Jul 20, 2005 3:38 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 20, 2005 3:36 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
dtabuenc wrote:
Your reply is very criptic. Is there no way to have a collection of derived classes if you are using the joined-subclass strategy? What is the issue that would make this not sane?


If you want a collection of subclass instances stick the fk where it belongs on the subclass table.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 20, 2005 3:37 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
By the way, have you heard of "polymorphism". It is a very useful concept in OO development :-)

All Hibernate associations can be polymorphic.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 21, 2005 2:12 pm 
Newbie

Joined: Fri May 06, 2005 6:04 pm
Posts: 11
Location: ES - Brazil
Hi,

I tought my problem was the same as this one when I asked if he had solved (2nd reply), but it´s actually diferent.

In my case , I´m getting a similar error message, but the FK is in the subclass (table per subclass with a discriminator).

So, I opened a new thread:
http://forum.hibernate.org/viewtopic.php?t=945292

and woud like to have some opinion if possible...

Thank´s in advance
Pedro


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 11, 2005 8:36 am 
Newbie

Joined: Tue Oct 11, 2005 8:13 am
Posts: 4
Gavin,

Have you ever heard about legacy applications? Really HUGE and unmodifiable legacy applications? They are evil! They have a lot of ugly modelling aspects, and usually the refactoring cost can buy a whole country... :D Sometimes, the database is not yours... :)

I'm creating a software that can be described as an "Open Source Toad", to manage Oracle databases. I'm using Hibernate to map Oracle's metadata tables, and it's very ugly. The index/table/user relationship is as follows:

Code:
class Index extends Object {
...
   private Table table;
...
}

class Table extends Object {
...
   private Set indexes;
...
}

class Object {
...
   private Owner owner;
...
}

class Owner {
...
   private Set tables;
...
}


The tables are:
    OBJECT: objId,type,...
    OWNER: userId,name,ownerId,...
    TABLE: objId,...
    INDEX: objId,tableId,...

Actually, it's simple to map it with inheritance, but the index/table relationship is a pain with Hibernate. When I map with "joined-subclass", the owner/table relationship (owner.getTables) does not work, because Hibernate do something like:

Code:
select * from object, table where table.ownerId = ?


Using discriminators (object.type) and join tables, owner.getTables works, but table/index (table.getIndexes) don't:

Code:
select * from object, index where object.tableId = ?


I think Hibernate should have some way to map this kind of thing.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 11, 2005 2:13 pm 
Newbie

Joined: Tue Oct 11, 2005 8:13 am
Posts: 4
Oops, sorry... Table examples are:

    OBJECT: objId,type,ownerId,...
    OWNER: userId,name,...
    TABLE: objId,...
    INDEX: objId,tableId,...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 12, 2005 2:51 pm 
Newbie

Joined: Wed Oct 12, 2005 2:13 pm
Posts: 3
I'm new to this but I have a lot of tables that have some core fields in common (they all have an ID and a creation date, etc) yet the tables themselves are not necessarily related to each other.

What I would like to do is to not have to type the same chunk of code in each and every one of these classes so I want to know if this is a valid way to handle this:

Tables:
Code:
User Table
----------
USER_ID
DATE_CREATED
NAME
ADDRESS_LINE


Item Table
----------
ITEM_ID
DATE_CREATED
NAME


Mappings
Code:
//
// User mapping
//
<hibernate-mapping>
   <class
      name="User" table="USER">
   <id
      name="id" column="USER_ID">
      <generator class="increment"/>
   </id>
   <property
      name="dateCreated" column="DATE_CREATED"/>
   <property
      name="name" column="NAME"/>
   <property
      name="address" column="ADDRESS_LINE"/>
   </class>
</hibernate-mapping>

//
// Item mapping
//
<hibernate-mapping>
   <class
      name="Item" table="ITEM">
   <id
      name="id" column="ITEM_ID">
      <generator class="increment"/>
   </id>
   <property
      name="dateCreated" column="DATE_CREATED"/>
   <property
      name="name" column="NAME"/>
   </class>
</hibernate-mapping>


As you can see, I'm trying to keep the stuff simple for this example...

and here are the classes as I'd like to see them:
Code:
//
// Class definitions
//
public class Basic_Class
{
   private Long id;
   private Date createdDate;

     // setters
   protected void setId(Long id) { this.id = id; }
   void setCreateDate(Date date) { createdDate = date; }

   // getters
   public Long getId()         { return id; }
   public Date getCreateDate() { return createdDate;  }
}

public class User extends Basic_Class
{
   private String name;
   private String address;

   // setters
   public void setName(String name)    { this.name = name; }
   public void setAddress(String addr) { this.address = addr; }

   // getters
   public String getName()    { return name; }
   public String getAddress() { return address; }
}

public class Item extends Basic_Class
{
   private String name;

   // setters
   public void setName(String name) { this.name = name; }

   // getters
   public String getName()          { return name; }
}


Is my usage of a base class (which has no immediate table associated with it) for these valid?

-Vel


Top
 Profile  
 
 Post subject: bump
PostPosted: Thu Oct 13, 2005 4:55 pm 
Newbie

Joined: Wed Oct 12, 2005 2:13 pm
Posts: 3
bumping this up.

-Vel


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