Hi,
I have been playing around with code and searching forums to no avail. Maybe someone here knows how to solve the following issue:
Abstract class A has B, C and D as subclasses. In SQL, these are represented by one table with a discriminator column.
Interface V is implemented by X, Y, and Z. In SQL, each of the subclasses is represented by a different table. All subclasses share certain attributes.
B has a collection of X's, C has a collection of Y's, and D has a collection of Z's.
When I try to fetch all instances of subclasses of A which conform to certain constraints in their collections, the queries I get are incorrect. Here's a more detailed look:
Code:
<class name="A" table="a" abstract="true">
<id name="id" type="java.lang.Integer">
<column name="id"/>
<generator class="sequence">
<param name="sequence">my_sequence</param>
</generator>
</id>
<discriminator column="discriminator" force="true"/> <!-- tried force="true", but did not help -->
<property name="example" type="java.lang.Integer">
<column name="example"/>
</property>
<subclass name="B" discriminator-value="0">
<set name="collection" cascade="all">
<key column="external_id" not-null="true"/>
<one-to-many class="X"/>
</set>
</subclass>
<subclass name="C" discriminator-value="1">
<set name="collection" cascade="all">
<key column="external_id" not-null="true"/>
<one-to-many class="Y"/>
</set>
</subclass>
<subclass name="C" discriminator-value="2">
<set name="collection" cascade="all">
<key column="external_id" not-null="true"/>
<one-to-many class="Z/>
</set>
</subclass>
</class>
public abstract class A {
...
}
public class B extends A {
...
Set<X> collections;
}
public class C extends A {
...
Set<Y> collections;
}
public class D extends A {
...
Set<Z> collections;
}
When I try an HQL query like
Code:
"from A as a left join a.collections as collection with collection.someAttribute = "foo" where id=?"
only one table is joined. That table is whatever happens to be the last entry in the XML file. In otherwords, the join is something like:
Code:
select [columns go here] from a left outer join z collection on a.id = collection.external_id and collection.someAttribute = 'foo' where id = ?
which is awesome, except that is neglects to check x and y, which may have pertinent rows as well. It's as if only the subclass that is last in the XML is examined in order to retrieve the join target.
I tried discriminator's force="true", but that did not help. The only thing I could think of is inserting another table with properties common to X, Y, and Z, with another discriminator or using a joined-subclass, as this would be a one-to-one relationship. But this seems somewhat awkward, and would introduce joins I shouldn't need into the SQL. In fact, the fact that X, Y and Z can implement a common interface is accidental. Hibernate is not aware of the fact they extend one interface., nor should it be. The collections could just as easily be three unrelated types.
I would expect Hibernate to be able to iterate over all "subclass" entries and generate the correct left outer joins with all three tables, instead of using whichever table is last in the XML.
Any ideas on how to solve this?
Thanks,
Eyal