Hibernate version: 3.2
Hello,
I am trying to solve a O/R mapping problem with a many-to-many relationship between the same table using an association class with Hibernate (of course). So here goes:
I have a generic class called a component. By my definition, a component can map to any other component. As practical example of how this will be used, lets think of logical software component called "trade processing component". This logical component maps to two physical components "app server" and "database server."
To describe this situation, I have created the following data model:
Table Component (
Component_ID Number Primary Key,
Component_Name Varchar2(4000)
);
Table Component_Mapping (
Comp_Mapping_ID Number Primary Key,
Logical_Component_ID Foreign Key References
Component(Component_ID),
Physical_Component_ID Foreign Key References
Component(Component_ID)
);
And the following object Model
class Component {
long id;
String name;
Set logicalComponentMappings;
Set physicalComponentMappings;
}
class ComponentMapping {
long id;
Component logicalComponent;
Component physicalComponent;
}
I have attempted to use Hibernate to map this situation with the following Hibernate mapping file
<hibernate-mapping default-access="field"
package="com.component"
default-cascade="none">
<class name="Component" table="COMPONENT">
<id name="id" column="COMPONENT_ID">
<generator class="sequence">
<param name="sequence">component_id_seq</param>
</generator>
</id>
<property name="name" column="COMPONENT_NAME" />
<set name="logicalComponentMappings" inverse="true" cascade="save-update">
<key column="PHYSICAL_COMPONENT_ID" />
<one-to-many class="ComponentMapping" />
</set>
<set name="physicalComponentMappings" inverse="true" cascade="save-update">
<key column="LOGICAL_COMPONENT_ID" />
<one-to-many class="ComponentMapping" />
</set>
</class>
<class name="ComponentMapping" table="COMPONENT_MAPPING">
<id name="id" column="COMP_MAPPING_ID">
<generator class="sequence">
<param name="sequence">comp_mapping_id_seq</param>
</generator>
</id>
<many-to-one name="logicalComponent" class="Component" column="COMPONENT_ID" />
<many-to-one name="physicalComponent" class="Component" column="COMPONENT_ID" />
</class>
</hibernate-mapping>
I have attempted to use this and I have encountered a lot of different error messages. I will post them here, but before I get into those details, I wanted to know if my fundamental approach is correct or not. If so, I will gladly post the different things I tried to make this work. I feel like there is a problem with the way I'm going about this.
As a final note, some justification for the above approach as it stands now:
1) Currently, I only know of two component types but there could be more later, so I want a very flexible data model underneath the covers of my application where any type of component can map to any other. There will be restrictions on what you can map, but I wanted to enforce those through the application rather than the schema and then offer configuration options to switch the restrictions on and off.
2) I'm using an association class because I want to easily have the ability to add properties about the mapping (time created, critical mapping flag, others potentially) relationship. Hibernate in action suggested that its better to create an association class that maps to the actual mapping table and establishes two one-to-many relationships to allow for this.
Thanks all,
Mike
P.S. The error message that prompted this post was: "hibernate mapping exception duplicate column component_id should be defined with update = "false" insert = "false". " Note that I tried adding this to the mapping file in all possible combinations with no success
|