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)
...
);