I have a generic mapping table that I need to map with hibernate.
I have the following db structure:
Code:
OBJECT_GROUP_MAP (
ID NUMBER,
GROUP_ID NUMBER, --FK to GROUPS.GROUP_ID
OBJECT_ID NUMBER,
OBJECT_TYPE NUMBER --discrimator
)
GROUPS (
GROUP_ID NUMBER,
NAME VARCHAR,
...
)
REPORTS (
REPORT_ID NUMBER,
NAME VARCHAR,
....
)
JOBS (
JOB_ID NUMBER,
NAME VARCHAR,
...
)
Job to Group mapping is held in OBJECT_GROUP_MAP with OBJECT_ID = JOBS.JOB_ID and OBJECT_GROUP_MAP.OBJECT_TYPE = 3. Similarly for REPORTS, but OBJECT_TYPE = 2. This is not a great relational model, but one I am stuck with. There are also many more entities that will have a relationship with a group.
If I were using a table for each relationship, for example, REPORT_GROUP_MAP and JOB_GROUP_MAP, I could do the following in hibernate, which I have had success with in the past:
Code:
<hibernate-mapping default-lazy="false">
<class name="x.y.z.Report" table="REPORTS">
<id name="id" column="REPORT_ID" type="java.lang.Integer" unsaved-value="null">
<generator class="native"/>
</id>
<property name="name" column="NAME" not-null="true" unique="true"/>
<set name="groups" table="REPORT_GROUP_MAP" cascade="all" inverse="true">
<key column="REPORT_ID"/>
<many-to-many column="GROUP_ID" class="x.y.z.Group"/>
</set>
</class>
<class name="x.y.z.Job" table="JOBS">
<id name="id" column="JOB_ID" type="java.lang.Integer" unsaved-value="null">
<generator class="native"/>
</id>
<property name="name" column="NAME" not-null="true" unique="true"/>
<set name="groups" table="JOB_GROUP_MAP" cascade="all" inverse="true">
<key column="JOB_ID"/>
<many-to-many column="GROUP_ID" class="x.y.z.Group"/>
</set>
</class>
<class name="x.y.z.Group" table="GROUPS">
<id name="id" column="GROUP_ID" type="java.lang.Integer" unsaved-value="null">
<generator class="native"/>
</id>
<property name="name" column="NAME" not-null="true" unique="true"/>
<set name="reports" table="REPORT_GROUP_MAP" cascade="all">
<key column="GROUP_ID"/>
<many-to-many column="REPORT_ID" class="x.y.z.Report"/>
</set>
<set name="jobs" table="JOB_GROUP_MAP" cascade="all">
<key column="GROUP_ID"/>
<many-to-many column="JOB_ID" class="x.y.z.Job"/>
</set>
</class>
However, because I have the generic mapping table, my only options would be to do one of 2 things:
1. use the where attribute of the set tag:
Code:
<set name="reports" table="OBJECT_GROUP_MAP" cascade="all" where="OBJECT_TYPE=2">
<key column="GROUP_ID"/>
<many-to-many column="OBJECT_ID" class="x.y.z.Report"/>
</set>
<set name="jobs" table="OBJECT_GROUP_MAP" cascade="all" where="OBJECT_TYPE=3">
<key column="GROUP_ID"/>
<many-to-many column="OBJECT_ID" class="x.y.z.Job"/>
</set>
2. Create a table-per-class heirarchy for my OBJECT_GROUP_MAP table (giving me ReportGroupMap and JobGroupMap objects) and having one-to-many relationships between Report and ReportGroupMap etc.
In option 1, that will not allow me to simply add a new job/report to the set and have it persist when I save the group. In option 2, it means having to create and manage another set of objects that are purely designed for relationship management.
Is there a better option?