My mapping is trying to describe the following inheritance hierarchy
interface FeatureSetting
interface Selective
class SimpleCallForwardSetting
implements FeatureSetting
class SelectiveCallForwardSetting
extends SimpleCallForwardSetting
implements Selective
class SwitchedSetting
implements FeatureSetting
class SelectiveSwitchedSetting
extends SwitchedSetting
implements Selective
The implementation of Selective (a mixin) takes the form of creating a one-to-many mapping of FeatureListMembers (implemented as a Set). The two classes which implement Selective have the extra Set , the other two classes don't. The Selective interface itself is not mentioned in the Hibernate mapping (see below).
I am trying to use the "Table Per Class Hierarchy" strategy, except, of course, for the Feature List Members themselves, which are in a related table.
This plan fails in the SQL Generation phase with a database error as follows:
Mar 21, 2006 2:48:07 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
SEVERE: Unsuccessful: alter table feature_list_member add constraint FKF123A19283A831E7 foreign key (feature_setting_id) references feature_setting
Mar 21, 2006 2:48:07 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
SEVERE: ORA-02275: such a referential constraint already exists in the table
This error makes perfect sense. Hibernate is trying to generate two instances of the same foreign key, one for each of the classes. (see generated DDL below).
My question is whether there's a better way to model this class hierarchy in Hibernate. I could, I suppose, keep the lists belonging to each hierarchical class in a different table, since there's no particular reason to lump them together. But is this necessary?
Hibernate version: 3.0.5
Mapping documents:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="blah.blah">
<class name="FeatureSetting" table="feature_setting">
<id name="id" type="long" column="feature_setting_id" >
<generator class="seqhilo">
<param name="sequence">feature_setting_seq</param>
<param name="max_lo">100</param>
</generator>
</id>
<discriminator
column="setting_type"
type="string"/>
<many-to-one name="parentPkg"
column="feature_package_id"
not-null="true"/>
<subclass name="SimpleCallForwardSetting"
discriminator-value="forward">
<property name="featureName">
<column name="feature_name" not-null="true"/>
</property>
<property name="destination" not-null="true"/>
<property name="ringCount" column="ring_count"/>
<property name="voiceMail" column="is_voice_mail"/>
</subclass>
<subclass name="SelectiveCallForwardSetting"
discriminator-value="selective-forward">
<property name="featureName">
<column name="feature_name" not-null="true"/>
</property>
<property name="destination" not-null="true"/>
<property name="ringCount" column="ring_count"/>
<property name="voiceMail" column="is_voice_mail"/>
<set name="callListMembers" table="feature_list_member">
<key column="feature_setting_id"/>
<one-to-many class="FeatureListMember" />
</set>
</subclass>
<subclass name="SwitchedSetting"
discriminator-value="switch">
<property name="featureName">
<column name="feature_name" not-null="true"/>
</property>
<property name="on" column="is_on"/>
</subclass>
<subclass name="SelectiveSwitchedSetting"
discriminator-value="selective">
<property name="featureName">
<column name="feature_name" not-null="true"/>
</property>
<property name="on" column="is_on"/>
<set name="listMembers" table="feature_list_member">
<key column="feature_setting_id"/>
<one-to-many class="FeatureListMember" />
</set>
</subclass>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close(): N/A, problem is in Generation phase
Full stack trace of any exception that occurs: No exception
Name and version of the database you are using: Oracle 9.2
The generated SQL (show_sql=true):
drop table feature_list_member cascade constraints;
drop table feature_package cascade constraints;
drop table feature_setting cascade constraints;
drop sequence feature_list_member_seq;
drop sequence feature_package_seq;
drop sequence feature_setting_seq;
create table feature_list_member (
feature_list_member_id number(19,0) not null,
rawTn varchar2(255) not null,
first_name varchar2(255),
last_name varchar2(255),
feature_setting_id number(19,0),
primary key (feature_list_member_id)
);
create table feature_package (
feature_package_id number(19,0) not null,
voip_account_id varchar2(255) not null,
sdp_account_id varchar2(255) not null,
primary key (feature_package_id)
);
create table feature_setting (
feature_setting_id number(19,0) not null,
setting_type varchar2(255) not null,
feature_package_id number(19,0) not null,
feature_name varchar2(255) not null,
destination varchar2(255) not null,
ring_count number(10,0),
is_voice_mail number(1,0),
is_on number(1,0),
primary key (feature_setting_id)
);
alter table feature_list_member
add constraint FKF123A1922892E865
foreign key (feature_setting_id)
references feature_setting;
alter table feature_list_member
add constraint FKF123A19283A831E7
foreign key (feature_setting_id)
references feature_setting;
alter table feature_setting
add constraint FK1D39DA0778E17A5E
foreign key (feature_package_id)
references feature_package;
create sequence feature_list_member_seq;
create sequence feature_package_seq;
create sequence feature_setting_seq;
|