我试图弄清楚如何通过一个包含一些元数据的连接表来映射两个表之间的关系。简而言之,这三个表代表一个表单的页面,每个页面可以包含任意数量的元素(问题)。由于某种原因,原始开发人员决定可以在多个表单上使用元素。这意味着用于对页面上的元素进行排序的权重列位于连接表中。
我如何用XML格式化它? (注释不是一种选择。)
对于联接表,我猜是这样的:
<class name="com.foo.bar.model.db.ApplicationPageElements"
table="APPLICATION_PAGE_ELEMENTS">
<composite-id name="id" class="com.foo.bar.model.db.ApplicationPageElementsKey">
<key-property name="pageId" column="page_id"/>
<key-property name="elementId" column="element_id"/>
</composite-id>
<property name="weight" type="java.lang.Long">
<column name="WEIGHT" precision="0" />
</property>
</class>
我的直觉让我想从ApplicationPage方面做这样的事情:
<set name="applicationElements" table="applicationPageElement">
<key column="page_id"/>
<many-to-many column="element_id" unique="true"
class="com.foo.bar.model.db.ApplicationElements" />
</set>
这就是我松弛下巴,盯着屏幕,呜咽的地方。
我们使用.hbm.xml文件来映射我们的数据库。我们还决定不更改我们的数据库。
有关如何在XML中映射此内容的任何想法吗?
答案 0 :(得分:3)
不要将application_page和application_element之间的关系视为多对多,而应将其视为从application_page到ApplicationPageElements的一对多关系以及从application_element到ApplicationPageElements的一对多关系。
在您的application_page xml映射中添加以下内容:
<set name="applicationElements" inverse="true">
<key column="page_id"/>
<one-to-many class="ApplicationPageElements"/>
</set>
page_id构成了连接表主键的一部分。因此,将集合标记为反向。
您对联接表的映射是正确的。但是,通过上面的连接表的更改当前映射,您可以从application_page导航到ApplicationPageElements。要从application_page导航到application_element(通过ApplicationPageElements),请在连接表映射中添加多对一关系。
<class name="com.foo.bar.model.db.ApplicationPageElements"
table="APPLICATION_PAGE_ELEMENTS">
<composite-id name="id" class="com.foo.bar.model.db.ApplicationPageElementsKey">
<key-property name="pageId" column="page_id"/>
<key-property name="elementId" column="element_id"/>
</composite-id>
<property name="weight" type="java.lang.Long">
<column name="WEIGHT" precision="0" />
</property>
<many-to-one name="elements" class="ApplicationElements"
column="element_id" not-null="true" insert="false" update="false"/>
<many-to-one name="page" class="ApplicationPage"
column="page_id" not-null="true" insert="false" update="false"/>
</class>
请注意,在上面的多对一映射中,insert和update属性设置为false。这是必要的,因为列被映射两次,一次在复合键中(负责插入值),再次映射到多对一关联。
上面的用例在书中详细提到:Java Persistence with Hibernate。